
function MinHeap(array, comparator) {

    /**
     * Storage for heap. 
     * @private
     */
    this.heap = array || new Array();

    /**
     * Default comparator used if an override is not provided.
     * @private
     */
    this.compare = comparator || function(item1, item2) {
        return item1 == item2 ? 0 : item1 < item2 ? -1 : 1;
    };

    /**
     * Retrieve the index of the left child of the node at index i.
     * @private
     */
    this.left = function(i) {
        return 2 * i + 1;
    };
    /**
     * Retrieve the index of the right child of the node at index i.
     * @private
     */
    this.right = function(i) {
        return 2 * i + 2;
    };
    /**
     * Retrieve the index of the parent of the node at index i.
     * @private
     */
    this.parent = function(i) {
        return Math.ceil(i / 2) - 1;
    };

    /**
     * Ensure that the contents of the heap don't violate the 
     * constraint. 
     * @private
     */
    this.heapify = function(i) {
        var lIdx = this.left(i);
        var rIdx = this.right(i);
        var smallest;
        if (lIdx < this.heap.length
                && this.compare(this.heap[lIdx], this.heap[i]) < 0) {
            smallest = lIdx;
        } else {
            smallest = i;
        }
        if (rIdx < this.heap.length
                && this.compare(this.heap[rIdx], this.heap[smallest]) < 0) {
            smallest = rIdx;
        }
        if (i != smallest) {
            var temp = this.heap[smallest];
            this.heap[smallest] = this.heap[i];
            this.heap[i] = temp;
            this.heapify(smallest);
        }
    };

    /**
     * Starting with the node at index i, move up the heap until parent value
     * is less than the node.
     * @private
     */
    this.siftUp = function(i) {
        var p = this.parent(i);
        if (p >= 0 && this.compare(this.heap[p], this.heap[i]) > 0) {
            var temp = this.heap[p];
            this.heap[p] = this.heap[i];
            this.heap[i] = temp;
            this.siftUp(p);
        }
    };

    /**
     * Heapify the contents of an array.
     * This function is called when an array is provided.
     * @private
     */
    this.heapifyArray = function() {
        // for loop starting from floor size/2 going up and heapify each.
        var i = Math.floor(this.heap.length / 2) - 1;
        for (; i >= 0; i--) {
        //  jstestdriver.console.log("i: ", i);
            this.heapify(i);
        }
    };

    // If an initial array was provided, then heapify the array.
    if (array != null) {
        this.heapifyArray();
    }
    ;
}

/**
 * Place an item in the heap.  
 * @param item
 * @function
 */
MinHeap.prototype.push = function(item) {
    this.heap.push(item);
    this.siftUp(this.heap.length - 1);
};

/**
 * Insert an item into the heap.
 * @param item
 * @function
 */
MinHeap.prototype.insert = function(item) {
    this.push(item);
};

/**
 * Pop the minimum valued item off of the heap. The heap is then updated 
 * to float the next smallest item to the top of the heap.
 * @returns the minimum value contained within the heap.
 * @function
 */
MinHeap.prototype.pop = function() {
    var value;
    if (this.heap.length > 1) {
        value = this.heap[0];
        // Put the bottom element at the top and let it drift down.
        this.heap[0] = this.heap.pop();
        this.heapify(0);
    } else {
        value = this.heap.pop();
    }
    return value;
};

/**
 * Remove the minimum item from the heap.
 * @returns the minimum value contained within the heap.
 * @function
 */
MinHeap.prototype.remove = function() {
    return this.pop();
};


/**
 * Returns the minimum value contained within the heap.  This will
 * not remove the value from the heap.
 * @returns the minimum value within the heap.
 * @function
 */
MinHeap.prototype.getMin = function() {
    return this.heap[0];
};

/**
 * Return the current number of elements within the heap.
 * @returns size of the heap.
 * @function
 */
MinHeap.prototype.size = function() {
    return this.heap.length;
};

(function() {
  var GameInput, Input, KeyCode, aabbIntersect, all, c, calculateDeflection, calculateSlide, contexts, fragFont, fragShape, identity, k, line, mult, primitiveSizeLookup, sign, sweptAABB, vertFont, vertShape;

  window.Font437 = (function() {
    function Font437(ctx) {
      var me;
      this.ready = false;
      this.fontTex = ctx.Texture();
      me = this;
      this.spr = ctx.SpriteRender();
      this.promise = this.fontTex.load("img/font.png").then(function() {
        me.ready = true;
        return me.spr.setSpriteSheet(me.fontTex, 8, 8);
      });
      this.worldTransform = new window.Transform2D();
      this.localTransform = new window.Transform2D();
      this.spr.setWorldTransform(this.worldTransform);
    }

    Font437.prototype.use = function() {
      return this.spr.use();
    };

    Font437.prototype.drawOutlined = function(x, y, string, scale, r, g, b, a) {
      this.setColor(0.0, 0.0, 0.0, 1.0);
      this.drawString(x + scale, y, string, scale);
      this.setColor(r, g, b, a);
      return this.drawString(x, y, string, scale);
    };

    Font437.prototype.setColor = function(x, y, z, w) {
      return this.spr.setColor(x, y, z, w);
    };

    Font437.prototype.drawString = function(x, y, string, scale) {
      var charCode, column, row, _i, _ref;
      if (!this.ready) {
        return false;
      }
      if (scale == null) {
        scale = 1.0;
      }
      this.localTransform.setScale(scale);
      this.localTransform.setTranslation(x, y);
      for (x = _i = 0, _ref = string.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; x = 0 <= _ref ? ++_i : --_i) {
        charCode = string.charCodeAt(x);
        column = charCode >> 5;
        row = charCode - (column << 5);
        this.spr.drawSprite([row * 8, column * 8], this.localTransform);
        this.localTransform.translate(8 * scale, 0);
      }
      return true;
    };

    return Font437;

  })();

  contexts = {};

  window.Context = (function() {
    function Context(name, w, h) {
      this.name = name;
      if (w == null) {
        w = 800;
      }
      if (h == null) {
        h = 400;
      }
      contexts[this.name] = this;
      this.canvas = document.createElement("canvas");
      document.body.appendChild(this.canvas);
      this.gl = this.canvas.getContext("webgl", {
        premultipliedAlpha: false,
        alpha: false
      } || this.canvas.getContext("experimental-webgl", {
        premultipliedAlpha: false,
        alpha: false
      }));
      this.gl.enable(this.gl.BLEND);
      this.gl.blendFunc(this.gl.SRC_ALPHA, this.gl.ONE_MINUS_SRC_ALPHA);
      this.gl.clearColor(1, 1, 1, 1);
      this.gl.clear(this.gl.COLOR_BUFFER_BIT);
      this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
      this.gl.colorMask(true, true, true, false);
      this.setWidth(w);
      this.setHeight(h);
      this.clearColor(0.0, 0.0, 0.0, 1.0);
      this.clear();
    }

    Context.prototype.clearColor = function(x, y, z, w) {
      if (x == null) {
        x = 1.0;
      }
      if (y == null) {
        y = x;
      }
      if (z == null) {
        z = y;
      }
      if (w == null) {
        w = 1.0;
      }
      return this.gl.clearColor(x, y, z, w);
    };

    Context.prototype.getCanvas = function() {
      return this.canvas;
    };

    Context.prototype.screen = function() {
      return {
        x: 1.0 / (this.canvas.width / 2.0),
        y: -1.0 / (this.canvas.height / 2.0)
      };
    };

    Context.prototype.setWidth = function(w) {
      this.canvas.width = w;
      return this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
    };

    Context.prototype.setHeight = function(h) {
      this.canvas.height = h;
      return this.gl.viewport(0, 0, this.canvas.width, this.canvas.height);
    };

    Context.prototype.clear = function() {
      return this.gl.clear(this.gl.COLOR_BUFFER_BIT | this.gl.DEPTH_BUFFER_BIT);
    };

    Context.prototype.Texture = function() {
      return new window.Texture(this);
    };

    Context.prototype.Program = function() {
      return new window.Program(this);
    };

    Context.prototype.MeshBuffer = function(defaultSize) {
      return new window.MeshBuffer(this, defaultSize);
    };

    Context.prototype.SpriteRender = function() {
      return new window.SpriteRender(this);
    };

    Context.prototype.Font437 = function() {
      return new window.Font437(this);
    };

    return Context;

  })();

  window.getContext = function(name) {
    return contexts[name];
  };

  window.loadImage = function(src) {
    var defer, img;
    defer = new window.mq.Defer();
    img = new Image;
    img.src = src;
    img.onload = function() {
      return defer.resolve(img);
    };
    return defer;
  };

  KeyCode = {
    CANCEL: 3,
    HELP: 6,
    BACK_SPACE: 8,
    TAB: 9,
    CLEAR: 12,
    RETURN: 13,
    ENTER: 14,
    SHIFT: 16,
    CONTROL: 17,
    ALT: 18,
    PAUSE: 19,
    CAPS_LOCK: 20,
    ESCAPE: 27,
    SPACE: 32,
    PAGE_UP: 33,
    PAGE_DOWN: 34,
    END: 35,
    HOME: 36,
    LEFT: 37,
    UP: 38,
    RIGHT: 39,
    DOWN: 40,
    PRINTSCREEN: 44,
    INSERT: 45,
    DELETE: 46,
    0: 48,
    1: 49,
    2: 50,
    3: 51,
    4: 52,
    5: 53,
    6: 54,
    7: 55,
    8: 56,
    9: 57,
    SEMICOLON: 59,
    EQUALS: 61,
    A: 65,
    B: 66,
    C: 67,
    D: 68,
    E: 69,
    F: 70,
    G: 71,
    H: 72,
    I: 73,
    J: 74,
    K: 75,
    L: 76,
    M: 77,
    N: 78,
    O: 79,
    P: 80,
    Q: 81,
    R: 82,
    S: 83,
    T: 84,
    U: 85,
    V: 86,
    W: 87,
    X: 88,
    Y: 89,
    Z: 90,
    CONTEXT_MENU: 93,
    NUMPAD0: 96,
    NUMPAD1: 97,
    NUMPAD2: 98,
    NUMPAD3: 99,
    NUMPAD4: 100,
    NUMPAD5: 101,
    NUMPAD6: 102,
    NUMPAD7: 103,
    NUMPAD8: 104,
    NUMPAD9: 105,
    MULTIPLY: 106,
    ADD: 107,
    SEPARATOR: 108,
    SUBTRACT: 109,
    DECIMAL: 110,
    DIVIDE: 111,
    F1: 112,
    F2: 113,
    F3: 114,
    F4: 115,
    F5: 116,
    F6: 117,
    F7: 118,
    F8: 119,
    F9: 120,
    F10: 121,
    F11: 122,
    F12: 123,
    F13: 124,
    F14: 125,
    F15: 126,
    F16: 127,
    F17: 128,
    F18: 129,
    F19: 130,
    F20: 131,
    F21: 132,
    F22: 133,
    F23: 134,
    F24: 135,
    NUM_LOCK: 144,
    SCROLL_LOCK: 145,
    COMMA: 188,
    PERIOD: 190,
    SLASH: 191,
    BACK_QUOTE: 192,
    OPEN_BRACKET: 219,
    BACK_SLASH: 220,
    CLOSE_BRACKET: 221,
    QUOTE: 222,
    META: 224
  };

  Input = {
    state: {},
    isDown: function(code) {
      return this.state[code];
    }
  };

  all = [];

  for (k in KeyCode) {
    c = KeyCode[k];
    Input.state[c] = false;
    all.push(k);
  }

  GameInput = {
    createKey: function(name, keycodes) {
      if (keycodes.length === void 0) {
        keycodes = [keycodes];
      }
      keycodes = (function() {
        var _i, _len, _results;
        _results = [];
        for (_i = 0, _len = keycodes.length; _i < _len; _i++) {
          k = keycodes[_i];
          _results.push(KeyCode[k]);
        }
        return _results;
      })();
      GameInput[name] = {
        isDown: function() {
          var _i, _len;
          for (_i = 0, _len = keycodes.length; _i < _len; _i++) {
            k = keycodes[_i];
            if (Input.isDown(k)) {
              return true;
            }
          }
          return false;
        },
        isUp: function() {
          var _i, _len;
          for (_i = 0, _len = keycodes.length; _i < _len; _i++) {
            k = keycodes[_i];
            if (Input.isDown(k)) {
              return false;
            }
          }
          return true;
        }
      };
      return void 0;
    }
  };

  window.onkeydown = function(e) {
    return Input.state[e.which] = true;
  };

  window.onkeyup = function(e) {
    return Input.state[e.which] = false;
  };

  GameInput.createKey("any", all);

  window.Input = GameInput;

  primitiveSizeLookup = {
    FLOAT: 4,
    BYTE: 1,
    SHORT: 2,
    UNSIGNED_BYTE: 1,
    UNSIGNED_SHORT: 2
  };

  window.MeshBuffer = (function() {
    function MeshBuffer(ctx, defaultSize) {
      this.ctx = ctx;
      this.gl = this.ctx.gl;
      this.stride = 0;
      this.description = [];
      if (defaultSize == null) {
        defaultSize = 10000;
      }
      this.vsize = defaultSize;
      this.vhead = 0;
      this.isize = defaultSize;
      this.ihead = 0;
      this.verts = new Float32Array(this.vsize);
      this.idx = new Uint16Array(this.isize);
      this.idxBuff = this.gl.createBuffer();
      this.vertBuff = this.gl.createBuffer();
      this.vertexUsage = this.gl.STREAM_DRAW;
      this.indexUsage = this.gl.STREAM_DRAW;
    }

    MeshBuffer.prototype.clear = function() {
      this.vhead = 0;
      return this.ihead = 0;
    };

    MeshBuffer.prototype.addDescription = function(name, type, size, normalized) {
      if (normalized == null) {
        normalized = false;
      }
      this.description.push({
        name: name,
        type: this.gl[type],
        size: size,
        offset: this.stride,
        normalized: normalized
      });
      return this.stride += size * primitiveSizeLookup[type];
    };

    MeshBuffer.prototype.bindBuffers = function() {
      this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.vertBuff);
      return this.gl.bindBuffer(this.gl.ELEMENT_ARRAY_BUFFER, this.idxBuff);
    };

    MeshBuffer.prototype.finalize = function() {
      this.verts = new Float32Array(this.verts.subarray(0, this.vhead + 1));
      return this.idx = new Float32Array(this.idx.subarray(0, this.ihead + 1));
    };

    MeshBuffer.prototype.upload = function() {
      this.bindBuffers();
      this.gl.bufferData(this.gl.ARRAY_BUFFER, this.verts, this.vertexUsage);
      return this.gl.bufferData(this.gl.ELEMENT_ARRAY_BUFFER, this.idx, this.indexUsage);
    };

    MeshBuffer.prototype.pushf = function(x) {
      this.resizeVertsIfNeeded(1);
      this.verts[this.vhead] = x;
      return this.vhead += 1;
    };

    MeshBuffer.prototype.pushff = function(x, y) {
      this.resizeVertsIfNeeded(2);
      this.verts[this.vhead] = x;
      this.verts[this.vhead + 1] = y;
      return this.vhead += 2;
    };

    MeshBuffer.prototype.pushfff = function(x, y, z) {
      this.resizeVertsIfNeeded(3);
      this.verts[this.vhead] = x;
      this.verts[this.vhead + 1] = y;
      this.verts[this.vhead + 2] = z;
      return this.vhead += 3;
    };

    MeshBuffer.prototype.pushffff = function(x, y, z, w) {
      this.resizeVertsIfNeeded(4);
      this.verts[this.vhead] = x;
      this.verts[this.vhead + 1] = y;
      this.verts[this.vhead + 2] = z;
      this.verts[this.vhead + 3] = w;
      return this.vhead += 4;
    };

    MeshBuffer.prototype.setup = function(program) {
      var desc, loc, _i, _len, _ref, _results;
      this.bindBuffers();
      _ref = this.description;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        desc = _ref[_i];
        loc = this.gl.getAttribLocation(program.program, desc.name);
        this.gl.enableVertexAttribArray(loc);
        if (loc === -1) {
          console.error("Vertex attribute " + desc.name + " does not exist in shader");
        }
        _results.push(this.gl.vertexAttribPointer(loc, desc.size, desc.type, desc.normalized, this.stride, desc.offset));
      }
      return _results;
    };

    MeshBuffer.prototype.draw = function(mode, first, count) {
      if (first == null) {
        first = 0;
      }
      if (count == null) {
        count = this.ihead;
      }
      if (mode == null) {
        mode = this.gl.TRIANGLES;
      }
      return this.gl.drawElements(mode, count, this.gl.UNSIGNED_SHORT, first);
    };

    MeshBuffer.prototype.pushi = function(x) {
      this.resizeIdxIfNeeded(1);
      this.idx[this.ihead] = x;
      return this.ihead += 1;
    };

    MeshBuffer.prototype.pushii = function(x, y) {
      this.resizeIdxIfNeeded(2);
      this.idx[this.ihead] = x;
      this.idx[this.ihead + 1] = y;
      return this.ihead += 2;
    };

    MeshBuffer.prototype.pushiii = function(x, y, z) {
      this.resizeIdxIfNeeded(3);
      this.idx[this.ihead] = x;
      this.idx[this.ihead + 1] = y;
      this.idx[this.ihead + 2] = z;
      return this.ihead += 3;
    };

    MeshBuffer.prototype.resizeVertsIfNeeded = function(size) {
      var newBuff, newSize;
      if (this.vsize > this.vhead + size) {
        return false;
      }
      console.log("resizing vertices");
      newSize = this.vsize + this.vsize / 2;
      newBuff = new Float32Array(newSize);
      newBuff.set(this.verts);
      this.verts = newBuff;
      return this.vsize = newSize;
    };

    MeshBuffer.prototype.resizeIdxIfNeeded = function(size) {
      var newBuff, newSize;
      if (this.isize > this.ihead + size) {
        return false;
      }
      console.log("resizing index");
      newSize = this.isize + this.isize / 2;
      newBuff = new Uint16Array(newSize);
      newBuff.set(this.idx);
      this.idx = newBuff;
      return this.isize = newSize;
    };

    return MeshBuffer;

  })();

  window.mq = {};

  window.mq.Defer = (function() {
    function Defer() {
      this.pending = [];
      this.resolved = false;
      this.data = null;
    }

    Defer.prototype.then = function(fn) {
      var d;
      d = new window.mq.Defer();
      if (this.resolved) {
        d.resolve(fn(this.data));
      }
      if (!this.resolved) {
        this.pending.push([fn, d]);
      }
      return d;
    };

    Defer.prototype.resolve = function(data) {
      var dd, _i, _len, _ref, _results;
      this.data = data;
      this.resolved = true;
      _ref = this.pending;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        dd = _ref[_i];
        _results.push(dd[1].resolve(dd[0](data)));
      }
      return _results;
    };

    return Defer;

  })();

  window.mq.all = function(arr) {
    var data, defer, defered, resolved, toresolve, _i, _len;
    resolved = 0;
    toresolve = arr.length;
    defer = new window.mq.Defer();
    data = [];
    for (_i = 0, _len = arr.length; _i < _len; _i++) {
      defered = arr[_i];
      defered.then(function(d) {
        data.push(d);
        resolved += 1;
        if (resolved === toresolve) {
          return defer.resolve(data);
        }
      });
    }
    return defer;
  };

  window.mq.stream = function(arr) {
    var defer, defered, _i, _len;
    defer = new window.mq.Defer();
    for (_i = 0, _len = arr.length; _i < _len; _i++) {
      defered = arr[_i];
      defered.then(function(d) {
        return defer.resolve(d);
      });
    }
    return defer;
  };

  sign = function(v) {
    if (v === 0) {
      return 0;
    }
    if (v < 0) {
      return -1;
    }
    return 1;
  };

  calculateSlide = function(tiles, e, x0, y0, x1, y1) {
    var col, dx, dy, moved, standedOn, sx, sy, t, touched, v, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1;
    dx = x1 - x0;
    dy = y1 - y0;
    sx = sign(dx);
    sy = sign(dy);
    touched = {};
    standedOn = {};
    _ref = tiles.intersectNonSolid(x0, y0, e);
    for (_i = 0, _len = _ref.length; _i < _len; _i++) {
      t = _ref[_i];
      standedOn[t] = true;
      t.standingOn(e);
    }
    while (true) {
      moved = false;
      if (x0 !== x1 && sx !== 0) {
        col = tiles.intersectSolid(x0 + sx, y0, e);
        for (_j = 0, _len1 = col.length; _j < _len1; _j++) {
          v = col[_j];
          if (touched[v] === true) {
            continue;
          }
          v.touched(e);
          touched[v] = true;
        }
        if (col.length === 0) {
          x0 += sx;
          moved = true;
        }
      }
      if (y0 !== y1 && sy !== 0) {
        col = tiles.intersectSolid(x0, y0 + sy, e);
        for (_k = 0, _len2 = col.length; _k < _len2; _k++) {
          v = col[_k];
          if (touched[v] === true) {
            continue;
          }
          v.touched(e);
          touched[v] = true;
        }
        if (col.length === 0) {
          y0 += sy;
          moved = true;
        }
      }
      if (moved) {
        _ref1 = tiles.intersectNonSolid(x0, y0, e);
        for (_l = 0, _len3 = _ref1.length; _l < _len3; _l++) {
          t = _ref1[_l];
          if (standedOn[t] === true) {
            continue;
          }
          standedOn[t] = true;
          t.standingOn(e);
        }
      }
      if (!moved) {
        return [x0, y0];
      }
    }
  };

  calculateDeflection = function(t, x, y, w, h, dx, dy) {
    var b1, b2, col, remainingtime, sp, tile, tmin, vx, vy, _i, _len;
    b1 = {
      x: x,
      y: y,
      w: w,
      h: h,
      vx: dx,
      vy: dy
    };
    sp = [x, y, dx, dy];
    tmin = 1000000000;
    for (_i = 0, _len = t.length; _i < _len; _i++) {
      tile = t[_i];
      b2 = {
        x: tile.x,
        y: tile.y,
        w: 64,
        h: 64
      };
      col = window.physics.sweptAABB(b1, b2);
      if (col.t < tmin) {
        sp[0] = x + dx * col.t;
        sp[1] = y + dy * col.t;
        if (col.t === 1.0) {
          continue;
        }
        remainingtime = 1.0 - col.t;
        vx = dx;
        vy = dy;
        vx *= remainingtime;
        vy *= remainingtime;
        if (Math.abs(col.nx) > 0.0001) {
          vx = -vx;
        }
        if (Math.abs(col.ny) > 0.0001) {
          vy = -vy;
        }
        sp[2] = vx;
        sp[3] = vy;
      }
    }
    return sp;
  };

  aabbIntersect = function(a, b) {
    return (Math.abs(a.x - b.x) * 2 < (a.w + b.w)) && (Math.abs(a.y - b.y) * 2 < (a.h + b.h));
  };

  sweptAABB = function(b1, b2) {
    var entryTime, exitTime, normalx, normaly, xEntry, xExit, xInvEntry, xInvExit, yEntry, yExit, yInvEntry, yInvExit;
    if (aabbIntersect(b1, b2)) {
      return {
        t: 0.0,
        nx: 0,
        ny: 0
      };
    }
    xInvEntry = yInvEntry = xInvExit = yInvExit = 0.0;
    xEntry = yEntry = xExit = yExit = 0.0;
    if (b1.vx > 0.0) {
      xInvEntry = b2.x - (b1.x + b1.w);
      xInvExit = (b2.x + b2.w) - b1.x;
    } else {
      xInvEntry = (b2.x + b2.w) - b1.x;
      xInvExit = b2.x - (b1.x + b1.w);
    }
    if (b1.vy > 0.0) {
      yInvEntry = b2.y - (b1.y + b1.h);
      yInvExit = (b2.y + b2.h) - b1.y;
    } else {
      yInvEntry = (b2.y + b2.h) - b1.y;
      yInvExit = b2.y - (b1.y + b1.h);
    }
    if (b1.vx === 0.0) {
      xEntry = -Infinity;
      xExit = Infinity;
    } else {
      xEntry = xInvEntry / b1.vx;
      xExit = xInvExit / b1.vx;
    }
    if (b1.vy === 0.0) {
      yEntry = -Infinity;
      yExit = Infinity;
    } else {
      yEntry = yInvEntry / b1.vy;
      yExit = yInvExit / b1.vy;
    }
    if (yEntry > 1.0) {
      yEntry = -Infinity;
    }
    if (xEntry > 1.0) {
      xEntry = -Infinity;
    }
    entryTime = Math.max(xEntry, yEntry);
    exitTime = Math.min(xExit, yExit);
    if (xEntry > exitTime) {
      return {
        t: 1
      };
    }
    if (xEntry < 0.0 && yEntry < 0.0) {
      return {
        t: 1
      };
    }
    if (xEntry < 0.0 && (b1.x + b1.w < b2.x || b1.x > b2.x + b2.w)) {
      return {
        t: 1
      };
    }
    if (yEntry < 0.0 && (b1.y + b1.h < b2.y || b1.y > b2.y + b2.h)) {
      return {
        t: 1
      };
    }
    normalx = 0;
    normaly = 0;
    if (xEntry > yEntry) {
      if (xInvEntry < 0.0) {
        normalx = 1.0;
        normaly = 0.0;
      } else {
        normalx = -1.0;
        normaly = 0.0;
      }
    } else {
      if (yInvEntry < 0.0) {
        normalx = 0.0;
        normaly = 1.0;
      } else {
        normalx = 0.0;
        normaly = -1.0;
      }
    }
    return {
      nx: normalx * sign(b1.vx),
      ny: normaly * sign(b1.vy),
      t: entryTime
    };
  };

  line = function(x0, y0, x1, y1, fn) {
    var dx, dy, e2, err, sx, sy;
    x0 |= 0;
    y0 |= 0;
    x1 |= 0;
    y1 |= 0;
    dx = Math.abs(x1 - x0);
    dy = Math.abs(y1 - y0);
    sx = x0 < x1 ? 1 : -1;
    sy = y0 < y1 ? 1 : -1;
    err = dx - dy;
    while (true) {
      if (fn(x0, y0) === true) {
        return true;
      }
      if (x0 === x1 && y0 === y1) {
        return false;
      }
      e2 = 2 * err;
      if (e2 > -dy) {
        err -= dy;
        x0 += sx;
      }
      if (e2 < dx) {
        err += dx;
        y0 += sy;
      }
    }
  };

  window.physics = {
    sweptAABB: sweptAABB,
    line: line,
    calculateSlide: calculateSlide,
    calculateDeflection: calculateDeflection,
    sign: sign,
    dist: function(a, b) {
      var dx, dy;
      dx = a.x - b.x;
      dy = a.y - b.y;
      return Math.sqrt(dx * dx + dy * dy);
    }
  };

  window.Program = (function() {
    function Program(ctx) {
      this.ctx = ctx;
      this.gl = this.ctx.gl;
      this.vertexShader = this.gl.createShader(this.gl.VERTEX_SHADER);
      this.fragmentShader = this.gl.createShader(this.gl.FRAGMENT_SHADER);
      this.program = this.gl.createProgram();
    }

    Program.prototype.setFragSource = function(v) {
      this.gl.shaderSource(this.fragmentShader, v);
      this.gl.compileShader(this.fragmentShader);
      if (!this.gl.getShaderParameter(this.fragmentShader, this.gl.COMPILE_STATUS)) {
        console.error("ERROR in fragmentshader: \n" + this.gl.getShaderInfoLog(this.fragmentShader));
      }
      return this.gl.attachShader(this.program, this.fragmentShader);
    };

    Program.prototype.setVertSource = function(v) {
      this.gl.shaderSource(this.vertexShader, v);
      this.gl.compileShader(this.vertexShader);
      if (!this.gl.getShaderParameter(this.vertexShader, this.gl.COMPILE_STATUS)) {
        console.error("ERROR in vertexshader: \n" + this.gl.getShaderInfoLog(this.vertexShader));
      }
      return this.gl.attachShader(this.program, this.vertexShader);
    };

    Program.prototype.u1f = function(name, v) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform1f(l, v);
    };

    Program.prototype.u2f = function(name, x, y) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform2f(l, x, y);
    };

    Program.prototype.u3f = function(name, x, y, z) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform3f(l, x, y, z);
    };

    Program.prototype.u4f = function(name, x, y, z, w) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform4f(l, x, y, z, w);
    };

    Program.prototype.u1i = function(name, v) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform1i(l, v);
    };

    Program.prototype.u2i = function(name, x, y) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform2i(l, x, y);
    };

    Program.prototype.u3i = function(name, x, y, z) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform3i(l, x, y, z);
    };

    Program.prototype.u4i = function(name, x, y, z, w) {
      var l;
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniform4i(l, x, y, z, w);
    };

    Program.prototype.um2f = function(name, arr, t) {
      var l;
      if (t == null) {
        t = false;
      }
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniformMatrix2fv(l, t, arr);
    };

    Program.prototype.um3f = function(name, arr, t) {
      var l;
      if (t == null) {
        t = false;
      }
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniformMatrix3fv(l, t, arr);
    };

    Program.prototype.um4f = function(name, arr, t) {
      var l;
      if (t == null) {
        t = false;
      }
      l = this.gl.getUniformLocation(this.program, name);
      return this.gl.uniformMatrix4fv(l, t, arr);
    };

    Program.prototype.attachTexture = function(name, where, tex) {
      var me;
      me = this;
      return tex.loader.then(function() {
        me.gl.activeTexture(me.gl.TEXTURE0 + where);
        tex.bind();
        return me.u1i(name, where);
      });
    };

    Program.prototype.link = function() {
      this.gl.linkProgram(this.program);
      if (!this.gl.getProgramParameter(this.program, this.gl.LINK_STATUS)) {
        console.error("Error when linking program: \n " + (this.gl.getProgramInfoLog()));
      }
      this.gl.validateProgram(this.program);
      if (!this.gl.getProgramParameter(this.program, this.gl.VALIDATE_STATUS)) {
        return console.error("Error when linking program: \n " + (this.gl.getProgramInfoLog()));
      }
    };

    Program.prototype.use = function() {
      var a;
      this.gl.useProgram(this.program);
      a = this.ctx.screen();
      return this.u4f("screen", a.x, a.y, 1.0, 1.0);
    };

    return Program;

  })();

  window.rnd = {
    choose: function(arr) {
      var i;
      i = Math.random() * arr.length;
      i |= 0;
      return arr[i];
    },
    rndCell: function(bounds) {
      var dx, dy, x, y;
      dx = bounds[2] - bounds[0];
      dy = bounds[3] - bounds[1];
      x = dx * Math.random();
      x |= 0;
      x += bounds[0];
      y = dy * Math.random();
      y |= 0;
      y += bounds[1];
      return [x, y];
    },
    chooseRndCellInAreas: function(arr) {
      return window.rnd.rndCell(window.rnd.choose(arr));
    }
  };

  vertShape = "precision highp float;\nattribute vec2 vertex;\nattribute vec4 vertexColor;\n\nuniform vec4 screen;\n\nvarying lowp vec4 color;\nvoid main() { \n  gl_Position = vec4(vertex, 1.0, 1.0) * screen; \n  color = vertexColor;\n}";

  fragShape = "precision highp float;\nvarying lowp vec4 color;\n\nvoid main() { \n  gl_FragColor = color; \n}";

  window.ShapeRender = (function() {
    function ShapeRender(g) {
      this.g = g;
      this.buffOutline = this.g.ctx.MeshBuffer();
      this.buffOutline.addDescription("vertex", "FLOAT", 2);
      this.buffOutline.addDescription("vertexColor", "FLOAT", 4);
      this.buffSolid = this.g.ctx.MeshBuffer();
      this.buffSolid.addDescription("vertex", "FLOAT", 2);
      this.buffSolid.addDescription("vertexColor", "FLOAT", 4);
      this.prog = this.g.ctx.Program();
      this.prog.setFragSource(fragShape);
      this.prog.setVertSource(vertShape);
      this.prog.link();
      this.io = 0;
      this.is = 0;
    }

    ShapeRender.prototype.setTransform = function(world) {
      return this.prog.um3f(world.getMatrix());
    };

    ShapeRender.prototype.drawLine = function(x0, y0, x1, y1, r, g, b, a) {
      this.buffOutline.pushff(x0, y0);
      this.buffOutline.pushffff(r, g, b, a);
      this.buffOutline.pushff(x1, y1);
      this.buffOutline.pushffff(r, g, b, a);
      this.buffOutline.pushii(this.io, this.io + 1);
      return this.io += 2;
    };

    ShapeRender.prototype.drawRectFilled = function(x0, y0, x1, y1, r, g, b, a) {
      this.buffSolid.pushff(x0, y0);
      this.buffSolid.pushffff(r, g, b, a);
      this.buffSolid.pushff(x1, y0);
      this.buffSolid.pushffff(r, g, b, a);
      this.buffSolid.pushff(x1, y1);
      this.buffSolid.pushffff(r, g, b, a);
      this.buffSolid.pushff(x0, y1);
      this.buffSolid.pushffff(r, g, b, a);
      this.buffSolid.pushiii(this.is, this.is + 1, this.is + 2);
      this.buffSolid.pushiii(this.is, this.is + 3, this.is + 2);
      return this.is += 4;
    };

    ShapeRender.prototype.render = function() {
      this.g.ctx.gl.lineWidth(4.0);
      this.buffOutline.upload();
      this.buffSolid.upload();
      this.prog.use();
      this.buffOutline.setup(this.prog);
      this.buffOutline.draw(this.g.ctx.gl.LINES);
      this.buffOutline.clear();
      this.buffSolid.setup(this.prog);
      this.buffSolid.draw();
      this.buffSolid.clear();
      this.io = 0;
      return this.is = 0;
    };

    return ShapeRender;

  })();

  window.Animation = (function() {
    var resetFrame;

    function Animation(name, frames) {
      this.name = name;
      this.frames = frames;
      this.frame = 0;
      this.frameWait = 32;
      this.last = Date.now();
    }

    resetFrame = function() {
      return this.frame = 0;
    };

    Animation.prototype.fps = function(fps) {
      return this.frameWait = 1000 / fps;
    };

    Animation.prototype.getFrame = function() {
      var delta;
      delta = Date.now() - this.last;
      this.last = Date.now();
      delta /= this.frameWait;
      this.frame += delta;
      return this.frames[(this.frame | 0) % this.frames.length];
    };

    return Animation;

  })();

  window.Sprite = (function() {
    function Sprite(w, h) {
      this.w = w;
      this.h = h;
      this.current = null;
    }

    Sprite.prototype.addAnimation = function(anim) {
      return this[anim.name] = anim;
    };

    Sprite.prototype.getFrame = function() {
      var r;
      if (this.current === null) {
        return [0, 0];
      }
      r = this.current.getFrame();
      return [r[0] * this.w, r[1] * this.h];
    };

    return Sprite;

  })();

  vertFont = "precision highp float;\nattribute vec2 vertex; \n\n\nuniform mat3 spriteTransform; \nuniform vec4 screen;\nuniform vec2 frame;\nuniform vec2 spriteSheetSize;\n\nvarying highp vec2 coord;\n\nvoid main() { \n  vec3 homogeniousCoord = vec3(vertex, 1.0);\n  gl_Position = vec4(homogeniousCoord * spriteTransform, 1.0) * screen; \n  coord = (vertex + frame) / spriteSheetSize;\n}";

  fragFont = "precision highp float;\nvarying highp vec2 coord;\nuniform sampler2D spriteTexture;\nuniform vec4 color;\n \nvoid main() { \n  gl_FragColor = texture2D(spriteTexture, coord) * color; \n}";

  window.SpriteRender = (function() {
    function SpriteRender(ctx) {
      var identity;
      this.buff = ctx.MeshBuffer(8);
      this.buff.addDescription("vertex", "FLOAT", 2);
      identity = new window.Transform2D();
      this.prog = ctx.Program();
      this.prog.setFragSource(fragFont);
      this.prog.setVertSource(vertFont);
      this.prog.link();
      this.prog.use();
      this.worldTransform = new window.Transform2D();
      this.prog.u4f("color", 1.0, 1.0, 1.0, 1.0);
      this.prog.um3f("spriteTransform", identity.getMatrix());
      this.texture = null;
    }

    SpriteRender.prototype.setSpriteSheet = function(texture, w, h) {
      this.texture = texture;
      this.w = w;
      this.h = h;
      this.prog.use();
      this.buff.clear();
      this.buff.pushff(0.0, 0.0);
      this.buff.pushff(this.w, 0.0);
      this.buff.pushff(this.w, this.h);
      this.buff.pushff(0.0, this.h);
      this.buff.pushiii(0, 1, 2);
      this.buff.pushiii(2, 3, 0);
      return this.buff.upload();
    };

    SpriteRender.prototype.use = function() {
      this.prog.use();
      this.buff.setup(this.prog);
      this.prog.u2f("spriteSheetSize", this.texture.width, this.texture.height);
      return this.prog.attachTexture("spriteTexture", 0, this.texture);
    };

    SpriteRender.prototype.setColor = function(r, g, b, a) {
      return this.prog.u4f("color", r, g, b, a);
    };

    SpriteRender.prototype.setWorldTransform = function(worldTransform) {
      return this.worldTransform = worldTransform;
    };

    SpriteRender.prototype.drawSprite = function(frame, spriteTransform) {
      if (this.texture === null) {
        return false;
      }
      if (this.texture.ready === false) {
        return false;
      }
      spriteTransform.translate(this.worldTransform.t[2], this.worldTransform.t[5]);
      this.prog.u2f("frame", frame[0], frame[1]);
      this.prog.um3f("spriteTransform", spriteTransform.getMatrix());
      this.buff.draw();
      return true;
    };

    return SpriteRender;

  })();

  window.Texture = (function() {
    function Texture(ctx, type, imageFormat, formatType, internalFormat) {
      this.ctx = ctx;
      this.type = type;
      this.imageFormat = imageFormat;
      this.formatType = formatType;
      this.internalFormat = internalFormat;
      this.gl = this.ctx.gl;
      if (this.internalFormat == null) {
        this.internalFormat = this.gl.RGBA;
      }
      if (this.imageFormat == null) {
        this.imageFormat = this.gl.RGBA;
      }
      if (this.formatType == null) {
        this.formatType = this.gl.UNSIGNED_BYTE;
      }
      if (this.type == null) {
        this.type = this.gl.TEXTURE_2D;
      }
      this.texture = this.gl.createTexture();
      this.filterNearest();
      this.width = 0;
      this.height = 0;
      this.ready = false;
    }

    Texture.prototype.getSampler = function() {
      return this.texture;
    };

    Texture.prototype.bind = function() {
      return this.gl.bindTexture(this.type, this.texture);
    };

    Texture.prototype.setImageData = function(imgDefer) {
      var me, _defer;
      this.ready = false;
      _defer = new window.mq.Defer();
      this.loader = _defer;
      me = this;
      imgDefer.then(function(img) {
        me.ready = true;
        me.width = img.width;
        me.height = img.height;
        me.bind();
        me.gl.texImage2D(me.type, 0, me.internalFormat, me.imageFormat, me.formatType, img);
        return _defer.resolve(true);
      });
      return _defer;
    };

    Texture.prototype.load = function(src) {
      return this.setImageData(window.loadImage(src));
    };

    Texture.prototype.filterNearest = function() {
      this.bind();
      this.gl.texParameteri(this.type, this.gl.TEXTURE_MAG_FILTER, this.gl.NEAREST);
      return this.gl.texParameteri(this.type, this.gl.TEXTURE_MIN_FILTER, this.gl.NEAREST);
    };

    Texture.prototype.filterLinear = function() {
      this.bind();
      this.gl.texParameteri(this.type, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
      return this.gl.texParameteri(this.type, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
    };

    return Texture;

  })();

  identity = function() {
    return new Float32Array([1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]);
  };

  mult = function(a, b) {
    var d;
    d = new Float32Array(9);
    d[0] = a[0] * b[0] + a[1] * b[3] + a[2] * b[6];
    d[1] = a[0] * b[1] + a[1] * b[4] + a[2] * b[7];
    d[2] = a[0] * b[2] + a[1] * b[5] + a[2] * b[8];
    d[3] = a[3] * b[0] + a[4] * b[3] + a[5] * b[6];
    d[4] = a[3] * b[1] + a[4] * b[4] + a[5] * b[7];
    d[5] = a[3] * b[2] + a[4] * b[5] + a[5] * b[8];
    d[6] = a[6] * b[0] + a[7] * b[3] + a[8] * b[6];
    d[7] = a[6] * b[1] + a[7] * b[4] + a[8] * b[7];
    d[8] = a[6] * b[2] + a[7] * b[5] + a[8] * b[8];
    return d;
  };

  window.Transform2D = (function() {
    function Transform2D() {
      this.t = identity();
      this.r = identity();
      this.s = identity();
      this.rotation = 0.0;
    }

    Transform2D.prototype.setTranslation = function(x, y) {
      this.t[2] = x;
      return this.t[5] = y;
    };

    Transform2D.prototype.translate = function(x, y) {
      this.t[2] += x;
      return this.t[5] += y;
    };

    Transform2D.prototype.setRotation = function(d) {
      var cos, sin;
      this.rotation = d;
      cos = Math.cos(this.rotation);
      sin = Math.sin(this.rotation);
      this.r[0] = this.r[4] = cos;
      this.r[1] = -sin;
      return this.r[3] = sin;
    };

    Transform2D.prototype.rotate = function(d) {
      var cos, sin;
      this.rotation = d + this.rotation;
      cos = Math.cos(this.rotation);
      sin = Math.sin(this.rotation);
      this.r[0] = this.r[4] = cos;
      this.r[1] = -sin;
      return this.r[3] = sin;
    };

    Transform2D.prototype.setScale = function(sx, sy) {
      if (sy == null) {
        sy = sx;
      }
      this.s[0] = sx;
      return this.s[4] = sy;
    };

    Transform2D.prototype.scale = function(sx, sy) {
      if (sy == null) {
        sy = sx;
      }
      this.s[0] *= sx;
      return this.s[4] *= sy;
    };

    Transform2D.prototype.getMatrix = function() {
      return mult(this.t, this.s);
    };

    return Transform2D;

  })();

}).call(this);

(function() {
  var GuardAggressive, GuardAlert, GuardDeadState, GuardDoNothing, GuardPatrol, GuardSearch, GuardStateMachine, GuardWalkRandom, ctx, currentScreen, frag, inp, makeGuardSpr, runningDown, runningLeft, runningRight, runningUp, spr, standingDown, standingLeft, standingRight, standingUp, tableSprLookup, vert, wallLookup, _ref, _ref1, _ref10, _ref11, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7, _ref8, _ref9,
    __hasProp = {}.hasOwnProperty,
    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };

  window.Screen = (function() {
    function Screen() {}

    Screen.prototype.setLast = function(lastScreen) {
      this.lastScreen = lastScreen;
    };

    Screen.prototype.update = function() {};

    Screen.prototype.render = function() {};

    Screen.prototype.makeCurrent = function() {
      return window.makeCurrentScreen(this);
    };

    Screen.prototype.screenGoBack = function() {
      if (this.lastScreen !== null) {
        this.lastScreen.restore();
        return window.makeCurrentScreen(this.lastScreen);
      }
    };

    return Screen;

  })();

  window.Entity = (function() {
    function Entity() {}

    Entity.prototype.boffx = function() {
      return 0;
    };

    Entity.prototype.boffy = function() {
      return 0;
    };

    Entity.prototype.bwidth = function() {
      return 64;
    };

    Entity.prototype.bheight = function() {
      return 64;
    };

    Entity.prototype.die = function() {};

    Entity.prototype.isDead = function() {
      return this.health <= 0;
    };

    Entity.prototype.rest = function() {
      this.stammina += this.recovery;
      if (this.stammina > this.maxStammina) {
        return this.stammina = this.maxStammina;
      }
    };

    Entity.prototype.canRun = function() {
      return this.stammina >= 0;
    };

    Entity.prototype.hurt = function(hp) {
      this.health -= hp;
      console.log("Hurt! " + hp);
      if (this.health <= 0) {
        return this.die();
      }
    };

    Entity.prototype.addTag = function(tag) {
      return this.tags[tag] = true;
    };

    Entity.prototype.removeTag = function(tag) {
      return this.tags[tag] = false;
    };

    Entity.prototype.hasTag = function(tag) {
      return this.tags[tag] === true;
    };

    Entity.prototype.hasStammina = function(a) {
      if (a > this.stammina) {
        return false;
      }
      this.stammina -= a;
      return true;
    };

    Entity.prototype.init = function(g) {
      this.g = g;
      this.isRemoved = false;
      this.x = 0;
      this.y = 0;
      this.isCarrying = null;
      this.id = Math.random();
      this.tags = {};
      this.stammina = this.maxStammina = 100;
      this.health = this.maxHealth = 100;
      this.runningCost = 0.5;
      this.recovery = 0.25;
      this.transform = new window.Transform2D();
      this.transform.setScale(4, 4);
      this.height = 64;
      return this.strength = 20.0;
    };

    Entity.prototype.update = function() {};

    Entity.prototype.render = function() {};

    Entity.prototype.renderBBox = function() {
      var ox, oy, sp, x0, x1, y0, y1;
      ox = this.g.vx;
      oy = this.g.vy;
      sp = this.g.shapeRender;
      x0 = this.x + this.boffx() + ox;
      y0 = this.y + this.boffy() + oy;
      x1 = x0 + this.bwidth();
      y1 = y0 + this.bheight();
      return this.g.shapeRender.drawRectFilled(x0, y0, x1, y1, 1.0, 0.0, 0.0, 0.25);
    };

    Entity.prototype.slideCollide = function(info) {};

    Entity.prototype.collidedWith = function(who) {};

    return Entity;

  })();

  wallLookup = {
    0: [64, 432],
    1: [64, 448],
    2: [48, 432],
    3: [64, 496],
    4: [64, 416],
    5: [80, 480],
    6: [64, 464],
    7: [64, 480],
    8: [80, 432],
    9: [112, 496],
    10: [80, 464],
    11: [96, 496],
    12: [112, 464],
    13: [112, 480],
    14: [96, 464],
    15: [96, 480]
  };

  window.Tile = (function() {
    function Tile(g, x, y, t) {
      this.g = g;
      this.x = x;
      this.y = y;
      this.t = t;
      this.tileSpr = [0, 496];
      this.hasWall = false;
    }

    Tile.prototype.wallType = function() {
      var type, _ref, _ref1, _ref2, _ref3;
      type = 0;
      if ((_ref = this.t.getTile(this.x, this.y - 1)) != null ? _ref.isWall() : void 0) {
        type |= 1;
      }
      if ((_ref1 = this.t.getTile(this.x + 1, this.y)) != null ? _ref1.isWall() : void 0) {
        type |= 2;
      }
      if ((_ref2 = this.t.getTile(this.x, this.y + 1)) != null ? _ref2.isWall() : void 0) {
        type |= 4;
      }
      if ((_ref3 = this.t.getTile(this.x - 1, this.y)) != null ? _ref3.isWall() : void 0) {
        type |= 8;
      }
      return type;
    };

    Tile.prototype.getWallSprite = function() {
      var k, type;
      type = this.wallType();
      k = wallLookup[type];
      return k;
    };

    Tile.prototype.createTile = function(fn, fw) {
      var sprWall;
      fn(this.x, this.y, this.tileSpr[0], this.tileSpr[1]);
      if (!this.isWall()) {
        return;
      }
      sprWall = this.getWallSprite();
      return fw(this.x, this.y, sprWall[0], sprWall[1]);
    };

    Tile.prototype.isWall = function() {
      return this.hasWall;
    };

    Tile.prototype.solid = function() {
      return this.hasWall;
    };

    Tile.prototype.standingOn = function(e) {};

    Tile.prototype.touched = function(e) {};

    return Tile;

  })();

  window.Item = (function(_super) {
    __extends(Item, _super);

    function Item() {
      this.z = 0;
      this.dx = 0;
      this.dy = 0;
      this.weight = 0.01;
      this.zspeed = 0;
      this.carriedBy = null;
      this.spr = [0, 6 * 16];
      this.soundMultipler = 1.0;
      this.airFriction = 0.98;
      this.renderTransform = new window.Transform2D();
    }

    Item.prototype.init = function(g) {
      this.g = g;
      Item.__super__.init.call(this, this.g);
      return this.addTag("item");
    };

    Item.prototype.pickup = function(who) {
      who.isCarrying = this;
      this.carriedBy = who;
      return this.z = who.height;
    };

    Item.prototype.hurt = function() {};

    Item.prototype.hurl = function(who, dx, dy) {
      this.dx = dx;
      this.dy = dy;
      if (this.dx == null) {
        this.dx = 0;
      }
      if (this.dy == null) {
        this.dy = 0;
      }
      who.isCarrying = null;
      this.carriedBy = null;
      this.z = who.height;
      return this.zspeed = -1.0;
    };

    Item.prototype.handleCarried = function() {
      if (this.carriedBy === null) {
        return false;
      }
      this.x = this.carriedBy.x;
      return this.y = this.carriedBy.y;
    };

    Item.prototype.handleNotCarried = function() {
      if (this.carriedBy !== null) {
        return false;
      }
      if (this.z <= 0) {
        return false;
      }
      this.z -= this.zspeed;
      this.zspeed += 0.1;
      if (this.z < 0.0) {
        this.z = 0;
      }
      this.x += this.dx;
      this.dx *= this.airFriction;
      this.y += this.dy;
      return this.dy *= this.airFriction;
    };

    Item.prototype.slideCollide = function(c) {
      var l;
      if (this.carriedBy !== null) {
        return false;
      }
      this.x = c[0];
      this.y = c[1];
      l = this.dx * this.dx + this.dy * this.dy;
      this.g.makeSound(this.x, this.y, l * this.weight * 2.0 * this.soundMultipler);
      this.dx = this.dx * 0.25;
      return this.dy = this.dy * 0.25;
    };

    Item.prototype.collidedWith = function(who) {
      var l;
      if (this.isCarried()) {
        return false;
      }
      if (!who.hasTag("guard")) {
        return false;
      }
      if (who.isDead()) {
        return false;
      }
      l = this.dx * this.dx + this.dy * this.dy;
      this.g.makeSound(who.x, who.y, l * this.weight * this.soundMultipler);
      who.edx += this.dx;
      who.edy += this.dy;
      this.dx = this.dx * 0.25;
      this.dy = this.dy * 0.25;
      who.hurt(l * this.weight * 0.6);
      if (who.isDead()) {
        this.g.makeBlood(who.x, who.y);
      } else {
        who.agro();
      }
      return true;
    };

    Item.prototype.isCarried = function() {
      return this.carriedBy !== null;
    };

    Item.prototype.update = function() {
      this.handleCarried();
      return this.handleNotCarried();
    };

    Item.prototype.render = function() {
      this.transform.setTranslation(this.x, this.y - this.z);
      return this.g.draw.drawSprite(this.spr, this.transform);
    };

    return Item;

  })(window.Entity);

  window.BloodParticles = (function(_super) {
    __extends(BloodParticles, _super);

    function BloodParticles(number) {
      var x, _i, _ref;
      this.number = number;
      this.particles = [];
      for (x = _i = 0, _ref = this.number; 0 <= _ref ? _i <= _ref : _i >= _ref; x = 0 <= _ref ? ++_i : --_i) {
        this.particles.push({
          x: 0,
          y: 0,
          z: 0,
          dx: Math.random() * 2.0 - 1.0,
          dy: Math.random() * 2.0 - 1.0,
          dz: -Math.random() * 4.0,
          life: Math.random() * 75
        });
      }
    }

    BloodParticles.prototype.update = function() {
      var allDead, p, _i, _len, _ref;
      allDead = true;
      _ref = this.particles;
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        p = _ref[_i];
        if (p.life < 0.0) {
          continue;
        }
        allDead = false;
        p.x += p.dx;
        p.y += p.dy;
        p.z += p.dz;
        p.dz += 0.1;
        p.life -= 1.0;
      }
      if (allDead) {
        return this.update = function() {};
      }
    };

    BloodParticles.prototype.render = function() {
      var p, _i, _len, _ref, _results;
      _ref = this.particles;
      _results = [];
      for (_i = 0, _len = _ref.length; _i < _len; _i++) {
        p = _ref[_i];
        if (p.life < 0.0) {
          this.transform.setTranslation(p.x + this.x, p.y + this.y + p.z);
          _results.push(this.g.draw.drawSprite([8 * 16, 4 * 16], this.transform));
        } else {
          this.transform.setTranslation(p.x + this.x, p.y + this.y + p.z);
          _results.push(this.g.draw.drawSprite([7 * 16, 4 * 16], this.transform));
        }
      }
      return _results;
    };

    return BloodParticles;

  })(window.Entity);

  window.Bottle = (function(_super) {
    __extends(Bottle, _super);

    Bottle.prototype.bwidth = function() {
      return 6 * 4;
    };

    Bottle.prototype.bheight = function() {
      return 11 * 4;
    };

    Bottle.prototype.boffx = function() {
      return 7 * 4;
    };

    Bottle.prototype.boffy = function() {
      return 5 * 4;
    };

    function Bottle() {
      Bottle.__super__.constructor.call(this);
      this.weight = 0.30;
      this.spr = [32, 96];
      this.soundMultiplier = 3.0;
    }

    Bottle.prototype.slideCollide = function(s) {
      var e;
      if (!Bottle.__super__.slideCollide.call(this, s)) {
        return;
      }
      this.g.deleteEntity(this);
      e = this.g.addEntity(new window.GlassFragment());
      e.x = this.x;
      e.y = this.y;
      e = this.g.addEntity(new window.GlassFragment());
      e.x = this.x;
      return e.y = this.y;
    };

    Bottle.prototype.collidedWith = function(who) {
      var e;
      if (!Bottle.__super__.collidedWith.call(this, who)) {
        return;
      }
      this.g.deleteEntity(this);
      e = this.g.addEntity(new window.GlassFragment());
      e.x = this.x;
      e.y = this.y;
      this.g.makeBlood(e.x, e.y, 2);
      e = this.g.addEntity(new window.GlassFragment());
      e.x = this.x;
      return e.y = this.y;
    };

    return Bottle;

  })(window.Item);

  window.CellKey = (function(_super) {
    __extends(CellKey, _super);

    function CellKey() {
      CellKey.__super__.constructor.call(this);
      this.spr = [16, 96];
    }

    CellKey.prototype.init = function(g) {
      this.g = g;
      CellKey.__super__.init.call(this, this.g);
      return this.addTag("cellKey");
    };

    CellKey.prototype.bwidth = function() {
      return 10 * 4;
    };

    CellKey.prototype.bheight = function() {
      return 8 * 4;
    };

    CellKey.prototype.boffx = function() {
      return 3 * 4;
    };

    CellKey.prototype.boffy = function() {
      return 9 * 4;
    };

    return CellKey;

  })(window.Item);

  window.Door = (function(_super) {
    __extends(Door, _super);

    function Door(g, x, y, t) {
      this.g = g;
      this.x = x;
      this.y = y;
      this.t = t;
      Door.__super__.constructor.call(this, this.g, this.x, this.y, this.t);
      this.open = false;
      this.locked = true;
      this.openSpr = [32, 448];
      this.closedSpr = [16, 448];
      this.doorSpr = this.closedSpr;
      this.hasWall = false;
    }

    Door.prototype.solid = function() {
      return !this.open;
    };

    Door.prototype.openDoor = function(e) {
      this.open = true;
      this.locked = false;
      return this.doorSpr = this.openSpr;
    };

    Door.prototype.close = function(e) {
      this.open = false;
      this.locked = false;
      return this.doorSpr = this.closedSpr;
    };

    Door.prototype.isWall = function() {
      return true;
    };

    Door.prototype.getWallSprite = function() {
      var sx, sy, t, _ref;
      t = this.wallType();
      if (t === 10) {
        return this.doorSpr;
      }
      _ref = this.doorSpr, sx = _ref[0], sy = _ref[1];
      return [sx, sy - 16];
    };

    Door.prototype.touched = function(e) {
      if (e.hasTag("cellKey") && this.locked && !e.isCarried()) {
        this.openDoor();
        this.t.generateTileMesh();
        this.g.deleteEntity(e);
      }
      if ((e.hasTag("guard") || e.hasTag("player")) && !this.locked) {
        this.openDoor();
        return this.t.generateTileMesh();
      }
    };

    return Door;

  })(window.Tile);

  window.ExitTile = (function(_super) {
    __extends(ExitTile, _super);

    function ExitTile() {
      _ref = ExitTile.__super__.constructor.apply(this, arguments);
      return _ref;
    }

    ExitTile.prototype.solid = function() {
      return true;
    };

    ExitTile.prototype.isWall = function() {
      return true;
    };

    ExitTile.prototype.getWallSprite = function() {
      return [144, 448];
    };

    ExitTile.prototype.touched = function(e) {
      var ws;
      if (!e.hasTag("player")) {
        return;
      }
      ws = new window.WinScreen();
      return window.makeCurrentScreen(ws);
    };

    return ExitTile;

  })(window.Tile);

  window.FenceTile = (function(_super) {
    __extends(FenceTile, _super);

    function FenceTile() {
      _ref1 = FenceTile.__super__.constructor.apply(this, arguments);
      return _ref1;
    }

    FenceTile.prototype.solid = function() {
      return true;
    };

    FenceTile.prototype.isWall = function() {
      return true;
    };

    FenceTile.prototype.getWallSprite = function() {
      var x, y, _ref2;
      _ref2 = FenceTile.__super__.getWallSprite.call(this), x = _ref2[0], y = _ref2[1];
      return [x + 64, y];
    };

    return FenceTile;

  })(window.Tile);

  window.Game = (function(_super) {
    __extends(Game, _super);

    function Game(ctx) {
      this.ctx = ctx;
      this.inp = window.Input;
      this.draw = this.ctx.SpriteRender();
      this.shapeRender = new window.ShapeRender(this);
      this.vx = 0;
      this.vy = 0;
      this.textToRender = [];
      this.tiles = new window.Tilemap(this, 32, 32);
      this.restore();
      window.game = this;
    }

    Game.prototype.makeBlood = function(x, y, m) {
      var b;
      if (m == null) {
        m = 3;
      }
      b = new window.BloodParticles(4 + (3 * Math.random()) | 0);
      b.init(this);
      b.x = x;
      b.y = y;
      return this.blood.push(b);
    };

    Game.prototype.makeSound = function(x, y, loudness) {
      var d, dx, dy, e, _i, _len, _ref2, _results;
      if (loudness < 5.0) {
        return;
      }
      _ref2 = this.entities;
      _results = [];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        e = _ref2[_i];
        if (!e.hasTag("guard")) {
          continue;
        }
        if (e.isDead()) {
          continue;
        }
        dx = e.x - x;
        dy = e.y - y;
        d = Math.sqrt(dx * dx + dy * dy);
        if (d >= loudness) {
          continue;
        }
        _results.push(e.hear(x, y));
      }
      return _results;
    };

    Game.prototype.deleteEntity = function(e) {
      e.isRemoved = true;
      return this.entitiesToDelete.push(e);
    };

    Game.prototype.getTile = function(x, y) {
      return this.tiles.getTile(x, y);
    };

    Game.prototype.addEntity = function(e) {
      e.init(this);
      this.entities.push(e);
      return e;
    };

    Game.prototype.getEntities = function(fn) {
      var e, _i, _len, _ref2, _results;
      _ref2 = this.entities;
      _results = [];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        e = _ref2[_i];
        if (!fn(e)) {
          continue;
        }
        _results.push(e);
      }
      return _results;
    };

    Game.prototype.getEntitiesWithTag = function(tag) {
      var e, _i, _len, _ref2, _results;
      _ref2 = this.entities;
      _results = [];
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        e = _ref2[_i];
        if (!e.hasTag(tag)) {
          continue;
        }
        _results.push(e);
      }
      return _results;
    };

    Game.prototype.load = function() {
      var defer, imgPromise, me;
      defer = new window.mq.Defer();
      this.font = this.ctx.Font437();
      this.spriteSheet = this.ctx.Texture();
      imgPromise = this.spriteSheet.load("img/sprites.png");
      me = this;
      window.mq.all([this.font.promise, imgPromise]).then(function() {
        me.draw.setSpriteSheet(me.spriteSheet, 16, 16);
        return defer.resolve(true);
      });
      return defer;
    };

    Game.prototype.restore = function() {
      var wg;
      this.killCount = 0;
      this.unnoticed = true;
      this.alertedGuardsCount = 0;
      this.entitiesToDelete = [];
      this.entities = [];
      this.blood = [];
      wg = new window.WindowGenerator();
      this.tiles.tiles = {};
      wg.generateWorld(this, this.tiles);
      this.tiles.generateTileMesh();
      this.viewport = new window.Transform2D();
      return this.identity = new window.Transform2D();
    };

    Game.prototype.drawString = function(x, y, msg, scale, r, g, b, a) {
      return this.textToRender.push([x, y, msg, scale, r, g, b, a, false]);
    };

    Game.prototype.drawStringOutlined = function(x, y, msg, scale, r, g, b, a) {
      return this.textToRender.push([x, y, msg, scale, r, g, b, a, true]);
    };

    Game.prototype.update = function() {
      var b, b1, b2, collided, dx, dy, e, endx, endy, index, moving, o, slide, x0, x1, y0, y1, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref2, _ref3, _ref4, _ref5, _ref6, _results;
      _ref2 = this.entitiesToDelete;
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        e = _ref2[_i];
        index = this.entities.indexOf(e);
        if (index !== -1) {
          this.entities.splice(index, 1);
        }
      }
      this.entitiesToDelete = [];
      moving = [];
      _ref3 = this.blood;
      for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
        b = _ref3[_j];
        b.update();
      }
      _ref4 = this.entities;
      for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
        e = _ref4[_k];
        x0 = e.x | 0;
        y0 = e.y | 0;
        e.update();
        x1 = e.x | 0;
        y1 = e.y | 0;
        if (x0 !== x1 || y0 !== y1) {
          moving.push([x0, y0, x1, y1, e]);
        }
      }
      collided = [];
      for (_l = 0, _len3 = moving.length; _l < _len3; _l++) {
        _ref5 = moving[_l], x0 = _ref5[0], y0 = _ref5[1], x1 = _ref5[2], y1 = _ref5[3], e = _ref5[4];
        slide = window.physics.calculateSlide(this.tiles, e, x0, y0, x1, y1);
        if (slide[0] !== x1 || slide[1] !== y1) {
          e.slideCollide(slide);
        }
        endx = e.x;
        endy = e.y;
        collided.push([x0, y0, endx, endy, e]);
      }
      _results = [];
      for (_m = 0, _len4 = collided.length; _m < _len4; _m++) {
        _ref6 = collided[_m], x0 = _ref6[0], y0 = _ref6[1], x1 = _ref6[2], y1 = _ref6[3], e = _ref6[4];
        if (e.isRemoved === true) {
          continue;
        }
        dx = x1 - x0;
        dy = y1 - y0;
        b1 = {
          x: x0 + e.boffx(),
          y: y0 + e.boffy(),
          w: e.bwidth(),
          h: e.bheight(),
          vx: dx,
          vy: dy
        };
        _results.push((function() {
          var _len5, _n, _ref7, _results1;
          _ref7 = this.entities;
          _results1 = [];
          for (_n = 0, _len5 = _ref7.length; _n < _len5; _n++) {
            o = _ref7[_n];
            if (o.isRemoved === true || o === e) {
              continue;
            }
            b2 = {
              x: o.boffx() + o.x,
              y: o.boffy() + o.y,
              w: o.bwidth(),
              h: o.bheight()
            };
            if (window.physics.sweptAABB(b1, b2).t < 1.0) {
              _results1.push(e.collidedWith(o));
            } else {
              _results1.push(void 0);
            }
          }
          return _results1;
        }).call(this));
      }
      return _results;
    };

    Game.prototype.canSeeTile = function(e, t) {
      var tiles, x0, x1, y0, y1;
      tiles = this.tiles;
      x0 = (e.x / 64) | 0;
      y0 = (e.y / 64) | 0;
      x1 = t.x;
      y1 = t.y;
      return !window.physics.line(x0, y0, x1, y1, function(x, y) {
        if (x === x0 || y === y0 || x1 === x || y === y1) {
          return false;
        }
        if (tiles.isSolid(x0, y0, x1, y1)) {
          return true;
        }
        return false;
      });
    };

    Game.prototype.canSee = function(e, who) {
      var tiles, x0, x1, y0, y1;
      x0 = e.x;
      y0 = e.y;
      x1 = who.x;
      y1 = who.y;
      tiles = this.tiles;
      return !window.physics.line(x0, y0, x1, y1, function(x, y) {
        if (tiles.simpleIntersectSolid(x, y, e)) {
          return true;
        }
        return false;
      });
    };

    Game.prototype.getPath = function(e, x1, y1) {
      return this.tiles.pathFromTo(e, x1, y1);
    };

    Game.prototype.render = function() {
      var a, b, d, e, entitiesToRender, g, msg, o, r, scale, txt, x, y, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref2, _ref3, _ref4, _ref5;
      this.viewport.setTranslation(this.vx, this.vy);
      this.tiles.render();
      this.draw.use();
      this.draw.setWorldTransform(this.viewport);
      _ref2 = this.blood;
      for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
        b = _ref2[_i];
        b.render();
      }
      _ref3 = this.entities;
      for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
        d = _ref3[_j];
        if (d.isDead()) {
          d.render();
        }
      }
      entitiesToRender = [];
      _ref4 = this.entities;
      for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
        e = _ref4[_k];
        if (!e.isDead()) {
          entitiesToRender.push(e);
        }
      }
      entitiesToRender.sort(function(a, b) {
        return a.y + a.boffy() + a.bheight() > b.y + b.boffy() + b.bheight();
      });
      for (_l = 0, _len3 = entitiesToRender.length; _l < _len3; _l++) {
        e = entitiesToRender[_l];
        e.render();
      }
      this.draw.setWorldTransform(this.identity);
      this.shapeRender.render();
      this.font.use();
      _ref5 = this.textToRender;
      for (_m = 0, _len4 = _ref5.length; _m < _len4; _m++) {
        txt = _ref5[_m];
        x = txt[0], y = txt[1], msg = txt[2], scale = txt[3], r = txt[4], g = txt[5], b = txt[6], a = txt[7], o = txt[8];
        if (o === false) {
          this.font.drawString(x, y, msg, scale);
        }
        if (o === true) {
          this.font.drawOutlined(x, y, msg, scale, r, g, b, a);
        }
      }
      return this.textToRender = [];
    };

    return Game;

  })(window.Screen);

  window.GlassFragment = (function(_super) {
    __extends(GlassFragment, _super);

    GlassFragment.prototype.bwidth = function() {
      return 6 * 4;
    };

    GlassFragment.prototype.bheight = function() {
      return 11 * 4;
    };

    GlassFragment.prototype.boffx = function() {
      return 7 * 4;
    };

    GlassFragment.prototype.boffy = function() {
      return 5 * 4;
    };

    function GlassFragment() {
      GlassFragment.__super__.constructor.call(this);
      this.dx = Math.random() * 2.0 - 1.0;
      this.dy = Math.random() * 2.0 - 1.0;
      this.weight = 0.15;
      this.spr = window.rnd.choose([[32, 112], [32, 128], [32, 144]]);
      this.soundMultiplier = 1.5;
    }

    return GlassFragment;

  })(window.Item);

  makeGuardSpr = function() {
    var runningDown, runningLeft, runningRight, runningUp, spr, standingDown, standingLeft, standingRight, standingUp;
    standingUp = new window.Animation("standingUp", [[3, 4]]);
    standingDown = new window.Animation("standingDown", [[0, 4]]);
    standingLeft = new window.Animation("standingLeft", [[5, 5]]);
    standingRight = new window.Animation("standingRight", [[0, 5]]);
    runningUp = new window.Animation("runningUp", [[3, 4], [4, 4], [3, 4], [5, 4]]);
    runningUp.fps(10);
    runningDown = new window.Animation("runningDown", [[0, 4], [1, 4], [0, 4], [2, 4]]);
    runningDown.fps(10);
    runningRight = new window.Animation("runningRight", [[0, 5], [1, 5], [0, 5], [2, 5]]);
    runningRight.fps(10);
    runningLeft = new window.Animation("runningLeft", [[5, 5], [4, 5], [5, 5], [3, 5]]);
    runningLeft.fps(10);
    spr = new window.Sprite(16, 16);
    spr.addAnimation(new window.Animation("dead", [[6, 4]]));
    spr.addAnimation(standingUp);
    spr.addAnimation(standingDown);
    spr.addAnimation(standingLeft);
    spr.addAnimation(standingRight);
    spr.addAnimation(runningUp);
    spr.addAnimation(runningDown);
    spr.addAnimation(runningRight);
    spr.addAnimation(runningLeft);
    spr.current = spr.standingDown;
    return spr;
  };

  GuardStateMachine = (function() {
    function GuardStateMachine() {}

    GuardStateMachine.prototype.init = function(g) {
      this.g = g;
      this.game = this.g.g;
      this.nextCheck = Date.now() + 2000 + 1000 * Math.random();
      return this;
    };

    GuardStateMachine.prototype.stateInit = function() {};

    GuardStateMachine.prototype.step = function() {};

    GuardStateMachine.prototype.slideCollide = function() {};

    GuardStateMachine.prototype.collidedWith = function() {};

    GuardStateMachine.prototype.draw = function() {};

    GuardStateMachine.prototype.hear = function(x, y) {
      var s;
      if (this.g.state.isAlert === true) {
        return;
      }
      s = new GuardAlert();
      this.g.alertedGuardsCount += 1;
      s.ax = x;
      s.ay = y;
      console.log("Guard is alert!");
      return this.g.changeState(s);
    };

    GuardStateMachine.prototype.checkForDistractingObjects = function() {
      var alert, c, corpses, _i, _len;
      if (Date.now() < this.nextCheck) {
        return false;
      }
      this.nextCheck = Date.now() + 2000 + 1000 * Math.random();
      corpses = this.game.getEntitiesWithTag("corpse");
      for (_i = 0, _len = corpses.length; _i < _len; _i++) {
        c = corpses[_i];
        if (this.g.hasSeen(c) === true) {
          continue;
        }
        if (this.g.canSee(c)) {
          this.g.seen(c);
          alert = new GuardAlert(Date.now() + 5000 + 5000 * Math.random());
          this.g.alertedGuardsCount += 1;
          this.g.changeState(alert);
          alert.x = c.x;
          alert.y = c.y;
          return true;
        }
      }
      return false;
    };

    GuardStateMachine.prototype.checkPlayer = function() {
      var a, p;
      if (this.game === void 0) {
        return false;
      }
      p = this.game.getEntitiesWithTag("player")[0];
      if (p === void 0) {
        console.log("Player is does not exist.");
        return false;
      }
      if (p.isDead()) {
        return false;
      }
      if (this.g === void 0) {
        return false;
      }
      if (!this.g.canSee(p)) {
        return false;
      }
      a = new GuardAggressive();
      this.g.changeState(a);
      a.lastKnownX = p.x;
      a.lastKnownY = p.y;
      this.game.unnoticed = false;
      return true;
    };

    return GuardStateMachine;

  })();

  GuardAlert = (function(_super) {
    __extends(GuardAlert, _super);

    function GuardAlert() {
      _ref2 = GuardAlert.__super__.constructor.apply(this, arguments);
      return _ref2;
    }

    GuardAlert.prototype.init = function(g) {
      this.g = g;
      return GuardAlert.__super__.init.call(this, this.g);
    };

    GuardAlert.prototype.stateInit = function(alertDone) {
      if (alertDone == null) {
        alertDone = Date.now() + 1000 + 1000 * Math.random();
      }
      this.doneBeingAlert = alertDone;
      this.path = null;
      return this.isAlert = true;
    };

    GuardAlert.prototype.step = function() {
      var dx, dy, l, px, py, _ref3;
      if (this.checkPlayer()) {
        return;
      }
      if (Date.now() > this.doneBeingAlert) {
        this.g.changeState(new GuardSearch());
        console.log("No longer alert");
        return;
      }
      if (this.path === null) {
        this.path = this.game.getPath(this.g, this.ax, this.ay);
        if (this.path === null) {
          this.g.changeState(new GuardSearch());
          console.log("No longer alert");
          return;
        }
        this.pos = this.path.length - 1;
      }
      _ref3 = this.path[this.pos], px = _ref3[0], py = _ref3[1];
      dx = px - this.g.x;
      dy = py - this.g.y;
      l = dx * dx + dy * dy;
      if (l < 10.0) {
        this.pos -= 1;
      }
      this.g.move(dx, dy, true);
      if (this.pos < 0) {
        this.path = null;
      }
      if (this.path === null) {
        this.g.changeState(new GuardSearch());
        console.log("No longer alert");
      }
    };

    GuardAlert.prototype.draw = function() {
      this.g.transform.setTranslation(this.g.x, this.g.y - 64);
      return this.game.draw.drawSprite([96, 80], this.g.transform);
    };

    return GuardAlert;

  })(GuardStateMachine);

  GuardDoNothing = (function(_super) {
    __extends(GuardDoNothing, _super);

    function GuardDoNothing() {
      _ref3 = GuardDoNothing.__super__.constructor.apply(this, arguments);
      return _ref3;
    }

    GuardDoNothing.prototype.init = function(g) {
      this.g = g;
      return GuardDoNothing.__super__.init.call(this, this.g);
    };

    GuardDoNothing.prototype.stateInit = function() {
      return this.doneWaiting = Date.now() + 1000 + 1000 * Math.random();
    };

    GuardDoNothing.prototype.step = function() {
      var cls;
      if (this.checkForDistractingObjects()) {
        return;
      }
      if (this.checkPlayer()) {
        return;
      }
      if (Date.now() > this.doneWaiting) {
        cls = window.rnd.choose([GuardWalkRandom, GuardPatrol]);
        this.g.changeState(new cls());
      }
    };

    return GuardDoNothing;

  })(GuardStateMachine);

  GuardWalkRandom = (function(_super) {
    __extends(GuardWalkRandom, _super);

    function GuardWalkRandom() {
      _ref4 = GuardWalkRandom.__super__.constructor.apply(this, arguments);
      return _ref4;
    }

    GuardWalkRandom.prototype.init = function(g) {
      this.g = g;
      return GuardWalkRandom.__super__.init.call(this, this.g);
    };

    GuardWalkRandom.prototype.stateInit = function() {
      this.doneWalking = Date.now() + 1000 + 1000 * Math.random();
      this.dx = Math.random() * 2.0 - 1.0;
      return this.dy = Math.random() * 2.0 - 1.0;
    };

    GuardWalkRandom.prototype.step = function() {
      var cls;
      if (this.checkPlayer()) {
        return;
      }
      if (this.checkForDistractingObjects()) {
        return;
      }
      if (Date.now() > this.doneWalking) {
        cls = window.rnd.choose([GuardDoNothing, GuardPatrol]);
        this.g.changeState(new cls());
        return;
      }
      return this.g.move(this.dx, this.dy);
    };

    GuardWalkRandom.prototype.slideCollide = function() {
      return this.g.changeState(new GuardDoNothing());
    };

    return GuardWalkRandom;

  })(GuardStateMachine);

  GuardAggressive = (function(_super) {
    __extends(GuardAggressive, _super);

    function GuardAggressive() {
      _ref5 = GuardAggressive.__super__.constructor.apply(this, arguments);
      return _ref5;
    }

    GuardAggressive.prototype.init = function(g) {
      this.g = g;
      GuardAggressive.__super__.init.call(this, this.g);
      return this;
    };

    GuardAggressive.prototype.hear = function() {};

    GuardAggressive.prototype.stateInit = function() {
      var p, _ref6;
      p = (_ref6 = this.game) != null ? _ref6.getEntitiesWithTag("player")[0] : void 0;
      if (p === void 0) {
        this.g.changeState(new GuardDoNothing());
        return;
      }
      this.path = null;
      this.lastKnownX = p.x;
      return this.lastKnownY = p.y;
    };

    GuardAggressive.prototype.canSeePlayer = function() {
      var dx, dy, p, _ref6;
      p = (_ref6 = this.game) != null ? _ref6.getEntitiesWithTag("player")[0] : void 0;
      if (p === void 0) {
        this.g.changeState(new GuardDoNothing());
        return true;
      }
      this.p = p;
      if (this.p.isDead()) {
        this.g.changeState(new GuardDoNothing());
        return true;
      }
      dx = this.p.x - this.g.x;
      dy = this.p.y - this.g.y;
      if (!this.game.canSee(this.g, this.p)) {
        return false;
      }
      this.path = null;
      this.lastKnownX = this.p.x;
      this.lastKnownY = this.p.y;
      this.g.move(dx, dy, true);
      return true;
    };

    GuardAggressive.prototype.gotoLastKnownLocation = function() {
      var dx, dy, l, px, py, _ref6;
      if (this.lastKnownX === void 0 || this.lastKnownY === void 0) {
        this.g.changeState(new GuardSearch());
        return;
      }
      if (this.path === null || this.path === void 0) {
        this.path = this.game.getPath(this.g, this.lastKnownX, this.lastKnownY);
        if (this.path === null) {
          this.g.changeState(new GuardSearch());
          return;
        }
        if (this.path.length === 0) {
          this.g.changeState(new GuardSearch());
          return;
        }
        this.pos = this.path.length - 1;
      }
      _ref6 = this.path[this.pos], px = _ref6[0], py = _ref6[1];
      dx = px - this.g.x;
      dy = py - this.g.y;
      l = dx * dx + dy * dy;
      if (l < 10.0) {
        this.pos -= 1;
      }
      this.g.move(dx, dy, true);
      if (this.pos < 0) {
        this.path = null;
      }
      if (!this.game.canSee(this.g, this.p) && this.path === null) {
        this.g.changeState(new GuardSearch());
      }
    };

    GuardAggressive.prototype.step = function() {
      if (this.canSeePlayer()) {
        return;
      }
      return this.gotoLastKnownLocation();
    };

    return GuardAggressive;

  })(GuardStateMachine);

  GuardSearch = (function(_super) {
    __extends(GuardSearch, _super);

    function GuardSearch() {
      _ref6 = GuardSearch.__super__.constructor.apply(this, arguments);
      return _ref6;
    }

    GuardSearch.prototype.init = function(g) {
      this.g = g;
      return GuardSearch.__super__.init.call(this, this.g);
    };

    GuardSearch.prototype.stateInit = function() {
      var x, _i, _ref7, _results;
      this.path = null;
      this.pos = 0;
      this.dests = [];
      this.dpos = 0;
      _results = [];
      for (x = _i = 5, _ref7 = 5 + 5 * Math.random | 0; 5 <= _ref7 ? _i <= _ref7 : _i >= _ref7; x = 5 <= _ref7 ? ++_i : --_i) {
        _results.push(this.dests.push([this.g.x + 150 * Math.random(), this.g.y + 150 * Math.random()]));
      }
      return _results;
    };

    GuardSearch.prototype.goPath = function() {
      var dx, dy, l, px, py, _ref7;
      if (this.path === null) {
        return false;
      }
      if (this.pos < 0) {
        this.path = null;
        return false;
      }
      _ref7 = this.path[this.pos], px = _ref7[0], py = _ref7[1];
      dx = px - this.g.x;
      dy = py - this.g.y;
      l = dx * dx + dy * dy;
      if (l < 5.0) {
        this.pos -= 1;
      }
      this.g.move(dx, dy);
      return true;
    };

    GuardSearch.prototype.createPath = function() {
      var x, y, _ref7;
      if (this.dpos === this.dests.length) {
        this.g.changeState(new GuardDoNothing());
        console.log("Search failed could not find anything");
        return true;
      }
      _ref7 = this.dests[this.dpos], x = _ref7[0], y = _ref7[1];
      this.path = this.game.getPath(this.g, x, y);
      return this.dpos += 1;
    };

    GuardSearch.prototype.step = function() {
      if (this.checkPlayer()) {
        return;
      }
      if (this.checkForDistractingObjects()) {
        return;
      }
      if (this.goPath()) {
        return;
      }
      if (this.createPath()) {

      }
    };

    GuardSearch.prototype.draw = function() {
      this.g.transform.setTranslation(this.g.x, this.g.y - 64 + 4.0 * Math.sin(Date.now() / 1000.0));
      return this.game.draw.drawSprite([112, 80], this.g.transform);
    };

    return GuardSearch;

  })(GuardStateMachine);

  GuardDeadState = (function(_super) {
    __extends(GuardDeadState, _super);

    function GuardDeadState() {
      _ref7 = GuardDeadState.__super__.constructor.apply(this, arguments);
      return _ref7;
    }

    GuardDeadState.prototype.init = function(g) {
      this.g = g;
      return GuardDeadState.__super__.init.call(this, this.g);
    };

    return GuardDeadState;

  })(GuardStateMachine);

  GuardPatrol = (function(_super) {
    __extends(GuardPatrol, _super);

    function GuardPatrol() {
      _ref8 = GuardPatrol.__super__.constructor.apply(this, arguments);
      return _ref8;
    }

    GuardPatrol.prototype.init = function(g) {
      this.g = g;
      return GuardPatrol.__super__.init.call(this, this.g);
    };

    GuardPatrol.prototype.stateInit = function() {
      this.path = null;
      this.pos = 0;
      this.destx = this.x + Math.random() * 400 - 400;
      return this.desty = this.y + Math.random() * 400 - 400;
    };

    GuardPatrol.prototype.createPath = function() {
      if (this.path !== null) {
        return true;
      }
      if (this.game === void 0) {
        return false;
      }
      this.path = this.game.getPath(this.g, this.destx, this.desy);
      if (this.path === null) {
        return false;
      }
      this.pos = this.path.length - 1;
      return true;
    };

    GuardPatrol.prototype.step = function() {
      var dx, dy, l, px, py, _ref9;
      if (this.checkPlayer()) {
        return;
      }
      if (this.checkForDistractingObjects()) {
        return;
      }
      if (!this.createPath()) {
        this.g.changeState(new GuardWalkRandom());
        return;
      }
      _ref9 = this.path[this.pos], px = _ref9[0], py = _ref9[1];
      dx = px - this.g.x;
      dy = py - this.g.y;
      l = dx * dx + dy * dy;
      if (l < 5.0) {
        this.pos -= 1;
      }
      this.g.move(dx, dy);
      if (this.pos < 0) {
        this.g.changeState(new GuardDoNothing());
      }
    };

    return GuardPatrol;

  })(GuardStateMachine);

  window.Guard = (function(_super) {
    __extends(Guard, _super);

    Guard.prototype.hasSeen = function(i) {
      return this.seenItems[i] === true;
    };

    Guard.prototype.seen = function(i) {
      return this.seenItems[i] = true;
    };

    function Guard() {
      this.seenItems = {};
      this.s = this.spr = makeGuardSpr();
      this.standing = this.spr.standingDown;
      this.mdx = 0;
      this.mdy = 0;
      this.attackCD = 0;
      this.walkSpeed = 1.0;
      this.runningCooldown = 0;
      this.lx = 0;
      this.ly = 0;
      this.edx = 0;
      this.edy = 0;
      this.runningSpeed = 4.0 + Math.random();
      if (this.state === void 0) {
        this.changeState(new GuardDoNothing());
      }
    }

    Guard.prototype.init = function(g) {
      this.g = g;
      Guard.__super__.init.call(this, this.g);
      if (this.state === void 0) {
        return this.changeState(new GuardDoNothing());
      }
    };

    Guard.prototype.move = function(dx, dy, aggresive) {
      var l;
      if (aggresive == null) {
        aggresive = false;
      }
      l = dx * dx + dy * dy;
      if (l === 0) {
        return;
      }
      l = Math.sqrt(l);
      dx /= l;
      dy /= l;
      dx *= this.walkSpeed;
      dy *= this.walkSpeed;
      if (aggresive && this.runningCooldown <= 0) {
        dx *= this.runningSpeed;
        dy *= this.runningSpeed;
        this.stammina -= this.runningCost;
        if (this.stammina <= 0) {
          this.runningCooldown = 100;
        }
      } else {
        this.rest();
      }
      this.mdx = dx;
      return this.mdy = dy;
    };

    Guard.prototype.changeState = function(s) {
      this.state = s.init(this);
      this.state.stateInit();
      return this.state;
    };

    Guard.prototype.init = function(g) {
      this.g = g;
      Guard.__super__.init.call(this, this.g);
      return this.addTag("guard");
    };

    Guard.prototype.die = function() {
      var e;
      this.g.killCount += 1;
      this.s.current = this.s.dead;
      this.changeState(new GuardDeadState());
      this.g.deleteEntity(this);
      e = this.g.addEntity(new window.Corpse());
      e.x = this.x;
      e.y = this.y;
      if (Math.random() > 0.5) {
        return;
      }
      e = this.g.addEntity(new window.CellKey());
      e.z = 32.0;
      e.x = this.x;
      e.y = this.y;
      e.dx = Math.random() * 2.0 - 1.0;
      return e.dy = Math.random() * 2.0 - 1.0;
    };

    Guard.prototype.hear = function(x, y) {
      return this.state.hear(x, y);
    };

    Guard.prototype.update = function() {
      var maxx;
      this.edx *= 0.9;
      this.edy *= 0.9;
      this.runningCooldown -= 1;
      this.mdx = 0;
      this.attackCD -= 1;
      this.mdy = 0;
      this.state.step();
      maxx = Math.max(Math.abs(this.mdx), Math.abs(this.mdy));
      if (maxx === Math.abs(this.mdx)) {
        if (this.mdx < 0.0) {
          this.standing = this.s.standingLeft;
          this.s.current = this.s.runningLeft;
          this.lx = -1.0;
          this.ly = 0.0;
        }
        if (this.mdx > 0.0) {
          this.standing = this.s.standingRight;
          this.s.current = this.s.runningRight;
          this.lx = 1.0;
          this.ly = 0.0;
        }
      } else {
        if (this.mdy < 0.0) {
          this.standing = this.s.standingUp;
          this.s.current = this.s.runningUp;
          this.lx = 0.0;
          this.ly = -1.0;
        }
        if (this.mdy > 0.0) {
          this.standing = this.s.standingDown;
          this.s.current = this.s.runningDown;
          this.lx = 0.0;
          this.ly = 1.0;
        }
      }
      if (this.mdx === 0 && this.mdy === 0 && !this.isDead()) {
        this.s.current = this.standing;
      }
      this.x += this.mdx;
      this.y += this.mdy;
      this.x += this.edx;
      return this.y += this.edy;
    };

    Guard.prototype.agro = function() {
      if (this.state.isAggresive !== true) {
        return this.changeState(new GuardAggressive());
      }
    };

    Guard.prototype.slideCollide = function(s) {
      var _ref9;
      this.x = s[0];
      this.y = s[1];
      if ((_ref9 = this.state) != null) {
        _ref9.slideCollide(s);
      }
      return this.state.path = null;
    };

    Guard.prototype.collidedWith = function(o) {
      var _ref9;
      if (!o.hasTag("player")) {
        return;
      }
      if (this.attackCD > 0) {
        return;
      }
      if (this.isDead()) {
        return;
      }
      if ((_ref9 = this.state) != null) {
        _ref9.collidedWith(o);
      }
      o.hurt(25);
      o.edx += this.lx * 10;
      o.edy += this.ly * 10;
      return this.attackCD = 15;
    };

    Guard.prototype.render = function() {
      var frame;
      frame = this.s.getFrame();
      this.transform.setTranslation(this.x, this.y);
      this.g.draw.drawSprite(frame, this.transform);
      return this.state.draw();
    };

    Guard.prototype.canSee = function(who) {
      var dot, dx, dy;
      if (who === void 0) {
        return false;
      }
      dx = who.x - this.x;
      dy = who.y - this.y;
      dot = dx * this.lx + dy * this.ly;
      if (dot < 0.0) {
        return false;
      }
      return this.g.canSee(this, who);
    };

    Guard.prototype.boffx = function() {
      return 3 * 4;
    };

    Guard.prototype.boffy = function() {
      return 10 * 4;
    };

    Guard.prototype.bwidth = function() {
      return 10 * 4;
    };

    Guard.prototype.bheight = function() {
      return 6 * 4;
    };

    return Guard;

  })(window.Entity);

  window.Corpse = (function(_super) {
    __extends(Corpse, _super);

    Corpse.prototype.boffx = function() {
      return 3 * 4;
    };

    Corpse.prototype.boffy = function() {
      return 7 * 4;
    };

    Corpse.prototype.bwidth = function() {
      return 13 * 4;
    };

    Corpse.prototype.bheight = function() {
      return 10 * 4;
    };

    Corpse.prototype.init = function(g) {
      this.g = g;
      Corpse.__super__.init.call(this, this.g);
      return this.addTag("corpse");
    };

    Corpse.prototype.isDead = function() {
      return true;
    };

    function Corpse() {
      Corpse.__super__.constructor.call(this);
      this.weight = 4.0;
      this.spr = [96, 64];
    }

    Corpse.prototype.collidedWith = function(o) {
      return Corpse.__super__.collidedWith.call(this, o);
    };

    return Corpse;

  })(window.Item);

  window.LooseScreen = (function(_super) {
    __extends(LooseScreen, _super);

    function LooseScreen() {
      _ref9 = LooseScreen.__super__.constructor.apply(this, arguments);
      return _ref9;
    }

    LooseScreen.prototype.setLast = function(lastScreen) {
      this.lastScreen = lastScreen;
      this.font = this.lastScreen.font;
      this.cooldown = 100;
      return this.tip = Math.random() * 3.9 | 0;
    };

    LooseScreen.prototype.update = function() {
      this.cooldown -= 1;
      if (window.Input.any.isDown() && this.cooldown < 0) {
        return this.screenGoBack();
      }
    };

    LooseScreen.prototype.render = function() {
      this.font.setColor(1.0, 0.0, 0.0, 1.0);
      this.font.drawString(-250, -60, "You are dead...", 4.0);
      this.font.drawString(-380, -25, "Press any key to restart", 4.0);
      this.font.setColor(1.0, 1.0, 0.0, 1.0);
      if (this.tip === 0) {
        this.font.drawString(-250, 10, "(Visible bodies alert guards!)", 2.0);
      }
      if (this.tip === 1) {
        this.font.drawString(-350, 10, "(Breaking flasks and plates attract guards)", 2.0);
      }
      if (this.tip === 2) {
        this.font.drawString(-350, 10, "(Break line of sight, the AI gives up fast)", 2.0);
      }
      if (this.tip === 3) {
        return this.font.drawString(-310, 10, "(In a pinch, a corpse make fine weapon)", 2.0);
      }
    };

    return LooseScreen;

  })(Screen);

  inp = window.Input;

  inp.createKey("left", ["A", "LEFT"]);

  inp.createKey("right", ["D", "RIGHT"]);

  inp.createKey("up", ["W", "UP"]);

  inp.createKey("down", ["S", "DOWN"]);

  inp.createKey("run", ["SHIFT"]);

  inp.createKey("pickup", ["SPACE"]);

  inp.createKey("hurl", ["SPACE"]);

  inp.createKey("movement", ["A", "LEFT", "D", "RIGHT", "W", "DOWN", "S", "RIGHT"]);

  ctx = new window.Context("main", 800, 400);

  ctx.clearColor(0.0, 0.0, 0.0, 1.0);

  currentScreen = null;

  window.makeCurrentScreen = function(screen) {
    console.log(screen);
    screen.setLast(currentScreen);
    return currentScreen = screen;
  };

  window.onload = function() {
    var g, p, run;
    run = function() {
      currentScreen.update();
      return currentScreen.render();
    };
    g = new window.Game(ctx);
    p = g.load();
    return p.then(function() {
      window.makeCurrentScreen(g);
      return setInterval(run, 16);
    });
  };

  window.Plate = (function(_super) {
    __extends(Plate, _super);

    Plate.prototype.bwidth = function() {
      return 6 * 4;
    };

    Plate.prototype.bheight = function() {
      return 11 * 4;
    };

    Plate.prototype.boffx = function() {
      return 7 * 4;
    };

    Plate.prototype.boffy = function() {
      return 5 * 4;
    };

    function Plate() {
      Plate.__super__.constructor.call(this);
      this.weight = 0.25;
      this.spr = [48, 96];
      this.soundMultiplier = 2.5;
      this.airFriction = 1.0;
    }

    Plate.prototype.slideCollide = function(s) {
      var e;
      if (!Plate.__super__.slideCollide.call(this, s)) {
        return;
      }
      this.g.deleteEntity(this);
      e = this.g.addEntity(new window.PlateFragment());
      e.x = this.x;
      e.y = this.y;
      e = this.g.addEntity(new window.PlateFragment());
      e.x = this.x;
      return e.y = this.y;
    };

    Plate.prototype.collidedWith = function(who) {
      var e;
      if (!Plate.__super__.collidedWith.call(this, who)) {
        return;
      }
      this.g.deleteEntity(this);
      e = this.g.addEntity(new window.PlateFragment());
      e.x = this.x;
      e.y = this.y;
      e = this.g.addEntity(new window.PlateFragment());
      e.x = this.x;
      return e.y = this.y;
    };

    return Plate;

  })(window.Item);

  window.PlateFragment = (function(_super) {
    __extends(PlateFragment, _super);

    PlateFragment.prototype.bwidth = function() {
      return 6 * 4;
    };

    PlateFragment.prototype.bheight = function() {
      return 11 * 4;
    };

    PlateFragment.prototype.boffx = function() {
      return 7 * 4;
    };

    PlateFragment.prototype.boffy = function() {
      return 5 * 4;
    };

    function PlateFragment() {
      PlateFragment.__super__.constructor.call(this);
      this.dx = Math.random() * 2.0 - 1.0;
      this.dy = Math.random() * 2.0 - 1.0;
      this.weight = 0.15;
      this.spr = window.rnd.choose([[48, 112], [48, 128]]);
      this.soundMultiplier = 1.5;
      this.friction = 0.99;
    }

    return PlateFragment;

  })(window.Item);

  standingUp = new window.Animation("standingUp", [[3, 0]]);

  standingDown = new window.Animation("standingDown", [[0, 0]]);

  standingLeft = new window.Animation("standingLeft", [[5, 1]]);

  standingRight = new window.Animation("standingRight", [[0, 1]]);

  runningUp = new window.Animation("runningUp", [[3, 0], [4, 0], [3, 0], [5, 0]]);

  runningUp.fps(10);

  runningDown = new window.Animation("runningDown", [[0, 0], [1, 0], [0, 0], [2, 0]]);

  runningDown.fps(10);

  runningRight = new window.Animation("runningRight", [[0, 1], [1, 1], [0, 1], [2, 1]]);

  runningRight.fps(10);

  runningLeft = new window.Animation("runningLeft", [[5, 1], [4, 1], [5, 1], [3, 1]]);

  runningLeft.fps(10);

  spr = new window.Sprite(16, 16);

  spr.addAnimation(standingUp);

  spr.addAnimation(standingDown);

  spr.addAnimation(standingLeft);

  spr.addAnimation(standingRight);

  spr.addAnimation(new window.Animation("playerDead", [[6, 0]]));

  spr.addAnimation(runningUp);

  spr.addAnimation(runningDown);

  spr.addAnimation(runningLeft);

  spr.addAnimation(runningRight);

  spr.current = spr.standingDown;

  inp = window.Input;

  window.Player = (function(_super) {
    __extends(Player, _super);

    Player.prototype.boffx = function() {
      return 3 * 4;
    };

    Player.prototype.boffy = function() {
      return 10 * 4;
    };

    Player.prototype.bwidth = function() {
      return 10 * 4;
    };

    Player.prototype.bheight = function() {
      return 6 * 4;
    };

    function Player() {
      this.waiting = spr.current;
      this.walkingSpeed = 2.0;
      this.runningSpeed = 5.0;
      this.pickupCooldown = 0;
      this.edx = 0;
      this.edy = 0;
      this.ghost = false;
    }

    Player.prototype.init = function(g) {
      this.g = g;
      Player.__super__.init.call(this, this.g);
      return this.addTag("player");
    };

    Player.prototype.update = function() {
      var dx, dy, mdx, mdy, nearby, x0, y0;
      this.edx *= 0.90;
      this.edy *= 0.90;
      if (this.isDead()) {
        spr.current = spr.playerDead;
      }
      if (this.isDead()) {
        if (inp.any.isDown()) {
          this.g.restore();
        }
        return;
      }
      dx = 0;
      dy = 0;
      if (inp.left.isDown()) {
        spr.current = spr.runningLeft;
        this.waiting = spr.standingLeft;
        dx = -1;
      }
      if (inp.right.isDown()) {
        if (inp.right.isDown()) {
          spr.current = spr.runningRight;
        }
        if (inp.right.isDown()) {
          this.waiting = spr.standingRight;
        }
        dx = 1;
      }
      if (inp.up.isDown()) {
        if (inp.up.isDown()) {
          spr.current = spr.runningUp;
        }
        if (inp.up.isDown()) {
          this.waiting = spr.standingUp;
        }
        dy = -1;
      }
      if (inp.down.isDown()) {
        if (inp.down.isDown()) {
          spr.current = spr.runningDown;
        }
        if (inp.down.isDown()) {
          this.waiting = spr.standingDown;
        }
        dy = 1;
      }
      mdx = dx;
      mdy = dy;
      if (inp.movement.isDown() && inp.run.isDown() && this.canRun()) {
        mdx *= this.runningSpeed;
        mdy *= this.runningSpeed;
        this.stammina -= this.runningCost;
      } else {
        mdx *= this.walkingSpeed;
        mdy *= this.walkingSpeed;
        this.rest();
      }
      this.x += mdx;
      this.y += mdy;
      this.x += this.edx;
      this.y += this.edy;
      this.g.vx = -this.x | 0;
      this.g.vy = -this.y | 0;
      if (!inp.movement.isDown()) {
        spr.current = this.waiting;
      }
      this.pickupCooldown -= 1;
      if (inp.pickup.isDown() && this.pickupCooldown <= 0) {
        this.pickupCooldown = 10;
        if (this.isCarrying === null) {
          x0 = this.x;
          y0 = this.y;
          nearby = this.g.getEntities(function(e) {
            var length;
            if (!e.hasTag("item")) {
              return false;
            }
            dx = x0 - e.x;
            dy = y0 - e.y;
            length = dx * dx + dy * dy;
            if (length < 64 * 64) {
              return true;
            } else {
              return false;
            }
          });
          if (nearby.length !== 0) {
            return nearby[0].pickup(this);
          }
        } else {
          if (dx === 0 && dy === 0) {
            return this.isCarrying.hurl(this, 0, 0);
          } else {
            if (this.hasStammina(20.0 * this.isCarrying.weight)) {
              return this.isCarrying.hurl(this, dx * this.strength, dy * this.strength);
            }
          }
        }
      }
    };

    Player.prototype.renderUI = function() {
      var x, y;
      if (!this.isDead()) {
        x = -400;
        y = -200;
        this.g.shapeRender.drawRectFilled(x + 6, y + 6, x + 6 + 92 * (this.stammina / this.maxStammina), y + 18, 1.0, 1.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 4, x + 100, y + 4, 0.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 20, x + 100, y + 20, 0.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 4, x + 4, y + 20, 0.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 100, y + 4, x + 100, y + 20, 0.0, 0.0, 0.0, 1.0);
        x = -400;
        y = -170;
        this.g.shapeRender.drawRectFilled(x + 6, y + 6, x + 6 + 92 * (this.health / this.maxHealth), y + 18, 1.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 4, x + 100, y + 4, 0.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 20, x + 100, y + 20, 0.0, 0.0, 0.0, 1.0);
        this.g.shapeRender.drawLine(x + 4, y + 4, x + 4, y + 20, 0.0, 0.0, 0.0, 1.0);
        return this.g.shapeRender.drawLine(x + 100, y + 4, x + 100, y + 20, 0.0, 0.0, 0.0, 1.0);
      }
    };

    Player.prototype.die = function() {
      var screen;
      screen = new window.LooseScreen();
      return window.makeCurrentScreen(screen);
    };

    Player.prototype.render = function() {
      var x, y, _ref10;
      this.transform.setTranslation(this.x, this.y);
      if (this.isCarrying === null) {
        this.g.draw.drawSprite(spr.getFrame(), this.transform);
      } else {
        _ref10 = spr.getFrame(), x = _ref10[0], y = _ref10[1];
        this.g.draw.drawSprite([x, y + 32], this.transform);
      }
      return this.renderUI();
    };

    Player.prototype.slideCollide = function(s) {
      if (this.ghost) {
        return;
      }
      this.x = s[0];
      this.y = s[1];
      this.g.vx = -this.x;
      return this.g.vy = -this.y;
    };

    Player.prototype.collidedWith = function(e, s) {};

    return Player;

  })(window.Entity);

  window.Stone = (function(_super) {
    __extends(Stone, _super);

    Stone.prototype.bwidth = function() {
      return 10 * 4;
    };

    Stone.prototype.bheight = function() {
      return 6 * 4;
    };

    Stone.prototype.boffx = function() {
      return 3 * 4;
    };

    Stone.prototype.boffy = function() {
      return 10 * 4;
    };

    function Stone() {
      Stone.__super__.constructor.call(this);
      this.weight = 0.5;
    }

    Stone.prototype.collidedWith = function(who) {
      if (!Stone.__super__.collidedWith.call(this, who)) {
        return;
      }
      if (who.isDead()) {
        return this.spr = [0, 112];
      }
    };

    return Stone;

  })(window.Item);

  tableSprLookup = {
    0: [32, 400],
    2: [16, 416],
    8: [48, 416],
    10: [32, 416]
  };

  window.Table = (function(_super) {
    __extends(Table, _super);

    function Table() {
      _ref10 = Table.__super__.constructor.apply(this, arguments);
      return _ref10;
    }

    Table.prototype.solid = function() {
      return true;
    };

    Table.prototype.isWall = function() {
      return true;
    };

    Table.prototype.getWallSprite = function() {
      var t;
      t = this.wallType();
      t &= 10;
      return tableSprLookup[t];
    };

    return Table;

  })(window.Tile);

  vert = "precision highp float;\nattribute vec2 vertex; \nattribute vec2 vertexCoord; \n\n\nuniform mat3 worldTransform;  \nuniform vec4 screen;\nuniform vec2 spriteSheetSize;\n\nvarying highp vec2 coord;\n\nvoid main() { \n  vec3 homogeniousCoord = vec3(vertex, 1.0);\n  gl_Position = vec4(homogeniousCoord * worldTransform, 1.0) * screen; \n  coord = vertexCoord / spriteSheetSize;\n}";

  frag = " \nprecision highp float;\nvarying highp vec2 coord;\nuniform sampler2D spriteTexture; \nvoid main() { \n  gl_FragColor = texture2D(spriteTexture, coord) * vec4(1.0, 1.0, 1.0, 1.0); \n}";

  window.Tilemap = (function() {
    function Tilemap(g, xtiles, ytiles) {
      this.g = g;
      this.xtiles = xtiles;
      this.ytiles = ytiles;
      this.tiles = {};
      this.buffTiles = this.g.ctx.MeshBuffer(20000);
      this.buffWalls = this.g.ctx.MeshBuffer(20000);
      this.buffTiles.addDescription("vertex", "FLOAT", 2);
      this.buffTiles.addDescription("vertexCoord", "FLOAT", 2);
      this.buffWalls.addDescription("vertex", "FLOAT", 2);
      this.buffWalls.addDescription("vertexCoord", "FLOAT", 2);
      this.prog = this.g.ctx.Program();
      this.prog.setFragSource(frag);
      this.prog.setVertSource(vert);
      this.prog.link();
      this.tex = this.g.ctx.Texture();
      this.tex.load("img/sprites.png");
    }

    Tilemap.prototype.setTile = function(x, y, t) {
      return this.tiles[[x, y]] = t;
    };

    Tilemap.prototype.intersectSolid = function(x, y, e) {
      var h, out, t0, t1, t2, t3, w;
      x += e.boffx();
      y += e.boffy();
      w = e.bwidth();
      h = e.bheight();
      t0 = this.getTileDirect(x, y);
      t1 = this.getTileDirect(x + w, y);
      t2 = this.getTileDirect(x, y + h);
      t3 = this.getTileDirect(x + w, y + h);
      out = [];
      if (t0 !== void 0 && t0 !== null && t0.solid()) {
        out.push(t0);
      }
      if (t1 !== void 0 && t1 !== null && t1.solid()) {
        out.push(t1);
      }
      if (t2 !== void 0 && t2 !== null && t2.solid()) {
        out.push(t2);
      }
      if (t3 !== void 0 && t3 !== null && t3.solid()) {
        out.push(t3);
      }
      return out;
    };

    Tilemap.prototype.simpleIntersectSolid = function(x, y, e) {
      var h, t0, t1, t2, t3, w;
      x += e.boffx();
      y += e.boffy();
      w = e.bwidth();
      h = e.bheight();
      t0 = this.getTileDirect(x, y);
      t1 = this.getTileDirect(x + w, y);
      t2 = this.getTileDirect(x, y + h);
      t3 = this.getTileDirect(x + w, y + h);
      if (t0 !== void 0 && t0 !== null && t0.solid()) {
        return true;
      }
      if (t1 !== void 0 && t1 !== null && t1.solid()) {
        return true;
      }
      if (t2 !== void 0 && t2 !== null && t2.solid()) {
        return true;
      }
      if (t3 !== void 0 && t3 !== null && t3.solid()) {
        return true;
      }
      return false;
    };

    Tilemap.prototype.intersectNonSolid = function(x, y, e) {
      var h, out, t0, t1, t2, t3, w;
      x += e.boffx();
      y += e.boffy();
      w = e.bwidth();
      h = e.bheight();
      t0 = this.getTileDirect(x, y);
      t1 = this.getTileDirect(x + w, y);
      t2 = this.getTileDirect(x, y + h);
      t3 = this.getTileDirect(x + w, y + h);
      out = [];
      if (t0 !== void 0 && t0 !== null && !t0.solid()) {
        out.push(t0);
      }
      if (t1 !== void 0 && t1 !== null && !t1.solid()) {
        out.push(t1);
      }
      if (t2 !== void 0 && t2 !== null && !t2.solid()) {
        out.push(t2);
      }
      if (t3 !== void 0 && t3 !== null && !t3.solid()) {
        out.push(t3);
      }
      return out;
    };

    Tilemap.prototype.getTile = function(x, y) {
      return this.tiles[[x, y]];
    };

    Tilemap.prototype.isSolid = function(x, y) {
      var t;
      t = this.getTile(x, y);
      if (t === null) {
        return false;
      }
      return t.solid();
    };

    Tilemap.prototype.generateTileMesh = function() {
      var buffTiles, buffWalls, genTile, genWalls, i, k, n, v, _ref11;
      this.buffTiles.clear();
      this.buffWalls.clear();
      console.log("Regenerating tiles");
      i = 0;
      buffTiles = this.buffTiles;
      buffWalls = this.buffWalls;
      genTile = function(x, y, u, v) {
        buffTiles.pushff(x * 64, y * 64);
        buffTiles.pushff(u, v);
        buffTiles.pushff(x * 64 + 64, y * 64);
        buffTiles.pushff(u + 16, v);
        buffTiles.pushff(x * 64 + 64, y * 64 + 64);
        buffTiles.pushff(u + 16, v + 16);
        buffTiles.pushff(x * 64, y * 64 + 64);
        buffTiles.pushff(u, v + 16);
        buffTiles.pushiii(i, i + 1, i + 2);
        buffTiles.pushiii(i + 2, i + 3, i);
        return i += 4;
      };
      n = 0;
      genWalls = function(x, y, u, v) {
        buffWalls.pushff(x * 64, y * 64);
        buffWalls.pushff(u, v);
        buffWalls.pushff(x * 64 + 64, y * 64);
        buffWalls.pushff(u + 16, v);
        buffWalls.pushff(x * 64 + 64, y * 64 + 64);
        buffWalls.pushff(u + 16, v + 16);
        buffWalls.pushff(x * 64, y * 64 + 64);
        buffWalls.pushff(u, v + 16);
        buffWalls.pushiii(n, n + 1, n + 2);
        buffWalls.pushiii(n + 2, n + 3, n);
        return n += 4;
      };
      _ref11 = this.tiles;
      for (k in _ref11) {
        v = _ref11[k];
        if (v === null) {
          continue;
        }
        if (v.canSee === false) {
          continue;
        }
        v.createTile(genTile, genWalls);
      }
      this.buffWalls.upload();
      return this.buffTiles.upload();
    };

    Tilemap.prototype.render = function() {
      this.g.ctx.gl.lineWidth(1.0);
      this.prog.use();
      this.prog.u2f("spriteSheetSize", this.tex.width, this.tex.height);
      this.prog.um3f("worldTransform", this.g.viewport.getMatrix());
      this.prog.attachTexture("spriteTexture", 1, this.tex);
      this.buffTiles.setup(this.prog);
      this.buffTiles.draw();
      this.buffWalls.setup(this.prog);
      return this.buffWalls.draw();
    };

    Tilemap.prototype.addTileIfNotPresent = function(x, y) {
      var tile;
      tile = this.getTile(x, y);
      if (tile === void 0 || tile === null) {
        return this.setTile(x, y, new window.Tile(this.g, x, y, this));
      }
    };

    Tilemap.prototype.fillTilesIfNotThere = function(x0, y0, w, h, spr) {
      var t, x, y, _i, _j, _ref11, _ref12;
      for (x = _i = x0, _ref11 = x0 + w; x0 <= _ref11 ? _i <= _ref11 : _i >= _ref11; x = x0 <= _ref11 ? ++_i : --_i) {
        for (y = _j = y0, _ref12 = y0 + h; y0 <= _ref12 ? _j <= _ref12 : _j >= _ref12; y = y0 <= _ref12 ? ++_j : --_j) {
          this.addTileIfNotPresent(x, y);
          if (spr !== void 0) {
            t = this.getTile(x, y);
            t.tileSpr = spr;
          }
        }
      }
      return void 0;
    };

    Tilemap.prototype.getTileDirect = function(x, y) {
      return this.getTile((x / 64) | 0, (y / 64) | 0);
    };

    Tilemap.prototype.makeWall = function(x, y) {
      var t;
      this.addTileIfNotPresent(x, y);
      t = this.getTile(x, y);
      if (t.open !== void 0) {
        return;
      }
      if (t !== null && t !== void 0) {
        return t.hasWall = true;
      }
    };

    Tilemap.prototype.removeWall = function(x, y) {
      var t;
      t = this.getTile(x, y);
      if (t !== null) {
        return t.hasWall = false;
      }
    };

    Tilemap.prototype.createDoorTile = function(x, y) {
      var t, t0;
      t = new window.Door(this.g, x, y, this);
      t0 = this.getTile(x, y);
      if (t0 !== void 0) {
        t.tileSpr = t0.tileSpr;
      }
      this.setTile(x, y, t);
      return t;
    };

    Tilemap.prototype.createTableTile = function(x, y) {
      var t, t0;
      t = new window.Table(this.g, x, y, this);
      t0 = this.getTile(x, y);
      if (t0 !== void 0) {
        t.tileSpr = t0.tileSpr;
      }
      this.setTile(x, y, t);
      return t;
    };

    Tilemap.prototype.setTileSprite = function(x, y, spr) {
      var t;
      t = this.getTile(x, y);
      if (t !== null) {
        return t.tileSpr = spr;
      }
    };

    Tilemap.prototype.pathFromTo = function(e, x1, y1) {
      var add, c, close, closest, constructPath, dist, h, last, lookup, me, node, stepSize, x, x0, y, y0;
      x0 = e.x;
      y0 = e.y;
      if (this.intersectSolid(x0, y0, e).length !== 0) {
        return null;
      }
      me = this;
      h = [];
      lookup = {};
      closest = 1000000000;
      close = null;
      dist = function(x, y) {
        return Math.abs(x0 - x) + Math.abs(y0 - y);
      };
      add = function(x, y, c, l) {
        var d, dx, dy, node;
        if (dist(x, y) > 750) {
          return;
        }
        if (lookup[[x, y]] === true) {
          return;
        }
        if (me.intersectSolid(x, y, e).length !== 0) {
          return;
        }
        lookup[[x, y]] = true;
        dx = x - x1;
        dy = y - y1;
        d = dx * dx + dy * dy;
        node = [x, y, c, l];
        if (d < closest) {
          close = node;
          closest = d;
        }
        h.push(node);
        return h.sort(function(x, y) {
          return x[2] < y[2];
        });
      };
      constructPath = function(node) {
        var c, l, out, x, y;
        out = [];
        while (node !== null) {
          x = node[0], y = node[1], c = node[2], l = node[3];
          out.push([x, y]);
          node = l;
        }
        return out;
      };
      stepSize = 20;
      h.push([x0, y0, 0, null]);
      while (h.length !== 0) {
        node = h.splice(h.length - 1, 1);
        node = node[0];
        x = node[0], y = node[1], c = node[2], last = node[3];
        if (Math.abs(x - x1) + Math.abs(y - y1) < stepSize * 2) {
          return constructPath(node);
        }
        add(x + stepSize, y, c + stepSize, node);
        add(x, y + stepSize, c + stepSize, node);
        add(x - stepSize, y, c + stepSize, node);
        add(x, y - stepSize, c + stepSize, node);
      }
      return constructPath(node);
    };

    Tilemap.prototype.makeFence = function(x, y) {
      var t, tt;
      t = new window.FenceTile(this.g, x, y, this);
      tt = this.getTile(x, y);
      if (tt !== null && t !== void 0) {
        t.tileSpr = tt.tileSpr;
      }
      return this.setTile(x, y, t);
    };

    Tilemap.prototype.makeExitTile = function(x, y) {
      var t, tt;
      t = new window.ExitTile(this.g, x, y, this);
      tt = this.getTile(x, y);
      if (tt !== null && t !== void 0) {
        t.tileSpr = tt.tileSpr;
      }
      return this.setTile(x, y, t);
    };

    return Tilemap;

  })();

  window.WinScreen = (function(_super) {
    __extends(WinScreen, _super);

    function WinScreen() {
      _ref11 = WinScreen.__super__.constructor.apply(this, arguments);
      return _ref11;
    }

    WinScreen.prototype.setLast = function(lastScreen) {
      this.lastScreen = lastScreen;
      this.font = this.lastScreen.font;
      return this.cooldown = 100;
    };

    WinScreen.prototype.update = function() {
      this.cooldown -= 1;
      if (window.Input.any.isDown() && this.cooldown < 0) {
        return this.screenGoBack();
      }
    };

    WinScreen.prototype.render = function() {
      var g;
      g = this.lastScreen;
      this.font.drawString(-380, -150, "You managed to escape!", 4.0);
      this.font.drawString(-225 + 50 * Math.sin(Date.now() / 1000.0), -110, "Press any key to restart", 2.0);
      this.font.drawString(-380, -90, "statistics: ", 2.0);
      if (g.killCount === 0) {
        this.font.drawString(-380, -70, "You killed no guards (Nice!)", 2.0);
      } else {
        this.font.drawString(-380, -70, "You killed " + g.killCount + " guards", 2.0);
      }
      if (g.alertedGuardsCount === 0) {
        this.font.drawString(-380, -50, "You didn't alert any guards (Are you a ninja?)", 2.0);
      } else {
        this.font.drawString(-380, -50, "You trigged the alert " + g.alertedGuardsCount + " times", 2.0);
      }
      if (g.unnoticed) {
        this.font.drawString(-380, -30, "You managed to escape unnoticed!", 2.0);
        this.font.drawString(-380, -10, "you're way better than me :)", 2.0);
      }
      this.font.drawString(-380, 30, "I hope you enjoyed my first Ludum Dare game", 2.0);
      this.font.drawString(-380, 50, "The game has a lot of quirks, and I am sorry if", 2.0);
      this.font.drawString(-380, 70, "you had to endure them..", 2.0);
      return this.font.drawString(-380, 100, "Thanks for playing!", 2.0);
    };

    return WinScreen;

  })(Screen);

  window.WindowGenerator = (function() {
    function WindowGenerator() {}

    WindowGenerator.prototype.createRoom = function(x0, y0, x1, y1) {
      var x, y, _i, _j, _results;
      for (x = _i = x0; x0 <= x1 ? _i <= x1 : _i >= x1; x = x0 <= x1 ? ++_i : --_i) {
        this.tiles.makeWall(x, y0);
        this.tiles.makeWall(x, y1);
      }
      _results = [];
      for (y = _j = y0; y0 <= y1 ? _j <= y1 : _j >= y1; y = y0 <= y1 ? ++_j : --_j) {
        this.tiles.makeWall(x0, y);
        _results.push(this.tiles.makeWall(x1, y));
      }
      return _results;
    };

    WindowGenerator.prototype.createCells = function(x0, y0, x1, y1) {
      var corridorPostions, dx, left, r, rooms, x, xCells, yy, _i, _j, _k, _ref12, _ref13, _ref14;
      this.tiles.fillTilesIfNotThere(x0, y0, x1 - x0, y1 - y0, [0, 496]);
      this.createRoom(x0, y0, x1, y1);
      dx = x1 - x0;
      left = dx - 1;
      rooms = [];
      corridorPostions = [];
      xCells = (left / 3) | 0;
      corridorPostions.push([x1 - 2, y0 + 1, x1 - 2, y1 - 1]);
      for (x = _i = 0, _ref12 = xCells - 1; 0 <= _ref12 ? _i <= _ref12 : _i >= _ref12; x = 0 <= _ref12 ? ++_i : --_i) {
        this.createRoom(x0 + x * 3, y0, x0 + x * 3 + 3, y0 + 3);
        this.tiles.createDoorTile(x0 + x * 3 + 1, y0 + 3);
        r = [x0 + x * 3 + 1, y0 + 1, x0 + x * 3 + 3, y0 + 3];
        rooms.push(r);
        this.tiles.fillTilesIfNotThere(r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]);
      }
      corridorPostions.push([x0 + 2, y0 + 4, x1 - 2, y0 + 5]);
      yy = y0 + 6;
      while (yy + 3 < y1 - 2) {
        for (x = _j = 0, _ref13 = xCells - 1; 0 <= _ref13 ? _j <= _ref13 : _j >= _ref13; x = 0 <= _ref13 ? ++_j : --_j) {
          r = [x0 + x * 3 + 1, yy + 1, x0 + x * 3 + 3, yy + 3];
          rooms.push(r);
          this.tiles.fillTilesIfNotThere(r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]);
          this.createRoom(x0 + x * 3, yy, x0 + x * 3 + 3, yy + 3);
          this.tiles.createDoorTile(x0 + x * 3 + 1, yy);
        }
        yy += 3;
        for (x = _k = 0, _ref14 = xCells - 1; 0 <= _ref14 ? _k <= _ref14 : _k >= _ref14; x = 0 <= _ref14 ? ++_k : --_k) {
          this.createRoom(x0 + x * 3, yy, x0 + x * 3 + 3, yy + 3);
          r = [x0 + x * 3 + 1, yy + 1, x0 + x * 3 + 3, yy + 3];
          rooms.push(r);
          this.tiles.fillTilesIfNotThere(r[0], r[1], r[2] - r[0], r[3] - r[1], [0, 480]);
          this.tiles.createDoorTile(x0 + x * 3 + 1, yy + 3);
        }
        corridorPostions.push([x0 + 2, yy + 4, x1 - 2, yy + 5]);
        yy += 6;
      }
      return [rooms, corridorPostions];
    };

    WindowGenerator.prototype.eqCell = function(a, b) {
      return a[0] === b[0] && a[1] === b[1] && a[2] === b[2] && a[3] === b[3];
    };

    WindowGenerator.prototype.generateWorld = function(game, tiles) {
      var c, cells, cellsCorridors, cx, diningCorridors, e, h, i, mx0, mx1, nw, nx, plCell, rw, sx, sy, table, tables, w, x, xx0, xx1, y, _i, _j, _k, _l, _len, _len1, _len2, _len3, _m, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17, _ref18, _ref19, _ref20, _ref21, _ref22;
      this.game = game;
      this.tiles = tiles;
      x = 0;
      y = 0;
      w = 12 + (Math.random() * 3 | 0) * 3;
      h = 15 + (Math.random() * 2 | 0) * 8 + 1;
      _ref12 = this.createCells(x, y, x + w, y + h), cells = _ref12[0], cellsCorridors = _ref12[1];
      plCell = window.rnd.choose(cells);
      _ref13 = window.rnd.rndCell(plCell), sx = _ref13[0], sy = _ref13[1];
      e = this.game.addEntity(new window.Player());
      e.x = sx * 64;
      e.y = sy * 64;
      for (_i = 0, _len = cellsCorridors.length; _i < _len; _i++) {
        c = cellsCorridors[_i];
        _ref14 = window.rnd.rndCell(c), sx = _ref14[0], sy = _ref14[1];
        e = this.game.addEntity(new window.Guard());
        e.x = sx * 64;
        e.y = sy * 64;
      }
      for (_j = 0, _len1 = cells.length; _j < _len1; _j++) {
        c = cells[_j];
        if (Math.random() > 0.5) {
          _ref15 = window.rnd.rndCell(c), sx = _ref15[0], sy = _ref15[1];
          e = this.game.addEntity(new window.Stone());
          e.x = sx * 64;
          e.y = sy * 64;
        }
        if (Math.random() > 0.9 && !this.eqCell(plCell, c)) {
          _ref16 = window.rnd.rndCell(c), sx = _ref16[0], sy = _ref16[1];
          e = this.game.addEntity(new window.CellKey());
          e.x = sx * 64;
          e.y = sy * 64;
        }
        if (Math.random() > 0.8) {
          _ref17 = window.rnd.rndCell(c), sx = _ref17[0], sy = _ref17[1];
          e = this.game.addEntity(new window.Bottle());
          e.x = sx * 64;
          e.y = sy * 64;
        }
      }
      y += h + 2;
      nx = Math.random() * w * 0.5 | 0;
      nw = 12 + (Math.random() * 4 | 0) * 4;
      xx0 = x + w;
      xx1 = nx + nw;
      mx0 = Math.max(nx, x);
      mx1 = Math.min(xx0, xx1);
      rw = (mx1 - mx0 - 2) * Math.random() | 0;
      this.tiles.fillTilesIfNotThere(nx, y - 2, 2, 2, [16, 480]);
      this.createRoom(nx, y - 2, nx + 2, y);
      this.createOpenDoorTile(nx + 1, y - 2);
      this.createOpenDoorTile(nx + 1, y);
      x = nx;
      w = nw;
      h = 15 + (Math.random() * 3 | 0) * 3 + 2;
      _ref18 = this.createDining(x, y, x + w, y + h), tables = _ref18[0], diningCorridors = _ref18[1];
      for (_k = 0, _len2 = tables.length; _k < _len2; _k++) {
        table = tables[_k];
        for (i = _l = 0; _l <= 3; i = ++_l) {
          if (Math.random() > 0.5) {
            _ref19 = window.rnd.rndCell(table), sx = _ref19[0], sy = _ref19[1];
            e = this.game.addEntity(new window.Plate());
            e.x = sx * 64;
            e.y = sy * 64;
          }
        }
      }
      for (_m = 0, _len3 = diningCorridors.length; _m < _len3; _m++) {
        c = diningCorridors[_m];
        _ref20 = window.rnd.rndCell(c), sx = _ref20[0], sy = _ref20[1];
        e = this.game.addEntity(new window.Guard());
        e.x = sx * 64;
        e.y = sy * 64;
      }
      y += h + 2;
      this.createCourtYard(x - 5, y, x + w + 5, y + 10);
      cx = x + w / 2;
      this.tiles.fillTilesIfNotThere(cx - 1, y - 2, 2, 2, [16, 480]);
      this.createRoom(cx - 1, y - 2, cx + 1, y);
      this.createOpenDoorTile(cx, y);
      this.createOpenDoorTile(cx, y - 2);
      _ref21 = window.rnd.rndCell(plCell), sx = _ref21[0], sy = _ref21[1];
      e = this.game.addEntity(new window.Stone());
      e.x = sx * 64;
      e.y = sy * 64;
      _ref22 = window.rnd.rndCell(plCell), sx = _ref22[0], sy = _ref22[1];
      e = this.game.addEntity(new window.CellKey());
      e.x = sx * 64;
      return e.y = sy * 64;
    };

    WindowGenerator.prototype.createOpenDoorTile = function(x, y) {
      var door;
      this.tiles.createDoorTile(x, y);
      door = this.tiles.getTile(x, y);
      door.locked = false;
      door.open = true;
      return door.doorSpr = door.openSpr;
    };

    WindowGenerator.prototype.createDining = function(x0, y0, x1, y1) {
      var corridors, cx, cy, hinner, tables, winner, x, y, _i, _j, _k, _ref12, _ref13, _ref14, _ref15, _ref16, _ref17;
      this.tiles.fillTilesIfNotThere(x0, y0, x1 - x0, y1 - y0, [16, 480]);
      this.createRoom(x0, y0, x1, y1);
      this.createRoom(x0 + 3, y0 + 3, x1, y1 - 3);
      winner = (x1 - 3) - (x0 + 3);
      hinner = (x1 - 3) - (x0 + 3);
      tables = [];
      corridors = [];
      cx = (x0 + x1) / 2;
      cy = (y0 + y1) / 2;
      corridors.push([x0 + 1, y0 + 1, x0 + 2, y1 - 1]);
      corridors.push([x0 + 1, y0 + 1, x1 - 1, y0 + 2]);
      corridors.push([x0 + 1, y1 - 2, x1 - 1, y1 - 1]);
      this.tiles.fillTilesIfNotThere(x0 + 3, y0 + 3, x1 - x0 - 3, y1 - y0 - 6, [32, 480]);
      this.createOpenDoorTile(cx, y0 + 3);
      this.createOpenDoorTile(cx, y1 - 3);
      this.createOpenDoorTile(x0 + 3, cy);
      for (y = _i = _ref12 = y0 + 5, _ref13 = y1 - 5; _i <= _ref13; y = _i += 3) {
        for (x = _j = _ref14 = x0 + 5, _ref15 = cx - 2; _ref14 <= _ref15 ? _j <= _ref15 : _j >= _ref15; x = _ref14 <= _ref15 ? ++_j : --_j) {
          this.tiles.createTableTile(x, y);
        }
        tables.push([x0 + 5, y, cx - 2, y + 1]);
        for (x = _k = _ref16 = cx + 2, _ref17 = x1 - 2; _ref16 <= _ref17 ? _k <= _ref17 : _k >= _ref17; x = _ref16 <= _ref17 ? ++_k : --_k) {
          this.tiles.createTableTile(x, y);
        }
        tables.push([cx + 2, y, x1 - 2, y + 1]);
      }
      return [tables, corridors];
    };

    WindowGenerator.prototype.createCourtYard = function(x0, y0, x1, y1) {
      var h, w, x, xe, y, _i, _j, _k, _ref12, _ref13, _ref14, _ref15;
      w = x1 - x0;
      h = y1 - y0;
      this.tiles.fillTilesIfNotThere(x0, y0, w, h, [0, 464]);
      this.tiles.fillTilesIfNotThere(x0 - 3, y0, 3, h, [16, 496]);
      this.tiles.fillTilesIfNotThere(x1, y0, 3, h, [16, 496]);
      this.tiles.fillTilesIfNotThere(x0 - 3, y1, w + 3, 3, [16, 496]);
      for (x = _i = x0; x0 <= x1 ? _i <= x1 : _i >= x1; x = x0 <= x1 ? ++_i : --_i) {
        this.tiles.makeWall(x, y0);
      }
      for (x = _j = _ref12 = x0 + 1, _ref13 = x1 - 1; _ref12 <= _ref13 ? _j <= _ref13 : _j >= _ref13; x = _ref12 <= _ref13 ? ++_j : --_j) {
        this.tiles.makeFence(x, y1 - 1);
      }
      for (y = _k = _ref14 = y0 + 1, _ref15 = y1 - 1; _ref14 <= _ref15 ? _k <= _ref15 : _k >= _ref15; y = _ref14 <= _ref15 ? ++_k : --_k) {
        this.tiles.makeFence(x0 + 1, y);
        this.tiles.makeFence(x1 - 1, y);
      }
      xe = x0 + (w - 2) * Math.random() | 0;
      return this.tiles.makeExitTile(xe, y1 - 1);
    };

    return WindowGenerator;

  })();

}).call(this);
